Coder Social home page Coder Social logo

paulmillr / micro-aes-gcm Goto Github PK

View Code? Open in Web Editor NEW
25.0 4.0 3.0 98 KB

0-dep wrapper around webcrypto AES-GCM. Has optional RFC 8452 SIV implementation.

License: MIT License

JavaScript 90.72% TypeScript 8.65% HTML 0.63%
secretbox aes aead noble encryption symmetric crypto cryptography decryption

micro-aes-gcm's Introduction

micro-aes-gcm

Warning

The repository has been merged into noble-ciphers. Please head to the new repo for updates.

npm install @noble/ciphers
const key = Uint8Array.from([
  64, 196, 127, 247, 172, 2, 34, 159, 6, 241, 30,
  174, 183, 229, 41, 114, 253, 122, 119, 168, 177,
  243, 155, 236, 164, 159, 98, 72, 162, 243, 224, 195,
]);
const message = 'Hello world';

// WAS: micro-aes-gcm
import * as aes from 'micro-aes-gcm';
const ciphertext = await aes.encrypt(key, aes.utils.utf8ToBytes(message));
const plaintext = await aes.decrypt(key, ciphertext);
console.log(aes.utils.bytesToUtf8(plaintext) === message);

// NOW: noble-ciphers
import { gcm } from '@noble/ciphers/aes';
import { bytesToUtf8, utf8ToBytes } from '@noble/ciphers/utils';
import { managedNonce } from '@noble/ciphers/webcrypto';
const aes = managedNonce(gcm)(key);
const ciphertext = aes.encrypt(utf8ToBytes(message));
const plaintext = aes.decrypt(key, ciphertext);
console.log(bytesToUtf8(plaintext) === message);

0-dep wrapper around webcrypto AES-GCM. Has optional RFC 8452 SIV implementation.

Inserts IV and MAC into the output iv + ciphertext + mac:

  • iv is 12 bytes; it's an CSPRNG-sourced initialization vector for AES-GCM mode.
  • ciphertext length depends on plaintext
  • mac is 16 bytes; AES-GCM calculates this authentication tag for us.
  • const c = await encrypt(key, plaintext), iv = c.slice(0, 12), mac = c.slice(-16);

Has optional implementation of AES-GCM-SIV RFC 8452 nonce-misuse resistance in a separate file.

Usage

npm install micro-aes-gcm

We support all major platforms and runtimes. For Deno, ensure to use npm specifier. For React Native, you may need a polyfill for webcrypto. For Node.js older than v19, use shim: if (!globalThis.crypto) globalThis.crypto = require('node:crypto').webcrypto;.

import * as aes from 'micro-aes-gcm';
const key = Uint8Array.from([
  64, 196, 127, 247, 172, 2, 34, 159, 6, 241, 30, 174, 183, 229, 41, 114, 253, 122, 119, 168, 177,
  243, 155, 236, 164, 159, 98, 72, 162, 243, 224, 195,
]);
const message = 'Hello world';
const ciphertext = await aes.encrypt(key, aes.utils.utf8ToBytes(message));
const plaintext = await aes.decrypt(key, ciphertext);
console.log(aes.utils.bytesToUtf8(plaintext) === message);
// Also works in browsers

API is:

function encrypt(key: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array>;
function decrypt(key: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array>;

SIV

import { AES } from 'micro-aes-gcm/siv.js';
const cr = await aes(KEY, NONCE);
await cr.encrypt(buf, AAD),

AES-GCM-SIV is designed to preserve both privacy and integrity even if nonces are repeated. To accomplish this, encryption is a function of a nonce, the plaintext message, and optional additional associated data (AAD). In the event a nonce is misused (i.e. used more than once), nothing is revealed except in the case that same message is encrypted multiple times with the same nonce. When that happens, an attacker is able to observe repeat encryptions, since encryption is a deterministic function of the nonce and message. However, beyond that, no additional information is revealed to the attacker. For this reason, AES-GCM-SIV is an ideal choice in cases that unique nonces cannot be guaranteed, such as multiple servers or network devices encrypting messages under the same key without coordination.

AEADs that can withstand nonce duplication are called “nonce-misuse resistant” and that name appears to have caused some people to believe that they are infinitely resistant. I.e. that an unlimited number of messages can be encrypted with a fixed nonce with no loss in security. That is not the case, and the term wasn't defined that way originally by Rogaway and Shrimpton (nor does their SIV mode have that property). So it's important to emphasise that AES-GCM-SIV (and nonce-misuse resistant modes in general) are not a magic invulnerability shield. Figure four and section five of the the paper give precise bounds but, if in doubt, consider AES-GCM-SIV to be a safety net for accidental nonce duplication and otherwise treat it like a traditional AEAD.

License

MIT (c) Paul Miller (https://paulmillr.com), see LICENSE file.

micro-aes-gcm's People

Contributors

aral avatar paulmillr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

storipress aral

micro-aes-gcm's Issues

Typecheck fails when importing from a project with stricter tsconfig

Hi @paulmillr ! 👋

Merry Christmas if you celebrate!

Firstly, thanks for your work on this project! Also huge shoutout, love the noble packages too! 😄

Today I used patch-package to patch [email protected] for the project I'm working on.

I have a typescript project that uses @tsconfig/node16-strictest and it seems like the defaults there are stricter than what this package uses. I added a few changes to make the typecheck happy in my project - mostly just assertions that don't affect anything at runtime, but one access change from .crypto to ['crypto'].

Just thought I'd let you know, definitely not high priority to fix but leaving this here for others to help them if they run into the same thing.

Also, unrelated, but any chance this could also export as Common JS?

Here are the errors that I got:

> tsc --noEmit

node_modules/micro-aes-gcm/index.ts(7,60): error TS4111: Property 'crypto' comes from an index signature, so it must be accessed with ['crypto'].
node_modules/micro-aes-gcm/index.ts(32,28): error TS2322: Type 'Uint8Array | undefined' is not assignable to type 'Uint8Array'.
  Type 'undefined' is not assignable to type 'Uint8Array'.
node_modules/micro-aes-gcm/index.ts(37,16): error TS2345: Argument of type 'Uint8Array | undefined' is not assignable to parameter of type 'ArrayLike<number>'.
  Type 'undefined' is not assignable to type 'ArrayLike<number>'.
node_modules/micro-aes-gcm/index.ts(38,12): error TS2532: Object is possibly 'undefined'.

Here is the diff that solved my problem:

diff --git a/node_modules/micro-aes-gcm/index.ts b/node_modules/micro-aes-gcm/index.ts
index 07c24fe..d6ca0f0 100644
--- a/node_modules/micro-aes-gcm/index.ts
+++ b/node_modules/micro-aes-gcm/index.ts
@@ -4,7 +4,7 @@ import * as nodeCrypto from 'crypto';
 declare const self: Record<string, any> | undefined;
 const crypto = {
   node: nodeCrypto,
-  web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
+  web: typeof self === 'object' && 'crypto' in self ? self['crypto'] : undefined,
 };
 
 // Caching slows it down 2-3x
@@ -29,11 +29,11 @@ function hexToBytes(hex: string): Uint8Array {
 function concatBytes(...arrays: Uint8Array[]): Uint8Array {
   if (!arrays.every((arr) => arr instanceof Uint8Array))
     throw new Error('Uint8Array list expected');
-  if (arrays.length === 1) return arrays[0];
+  if (arrays.length === 1) return arrays[0]!;
   const length = arrays.reduce((a, arr) => a + arr.length, 0);
   const result = new Uint8Array(length);
   for (let i = 0, pad = 0; i < arrays.length; i++) {
-    const arr = arrays[i];
+    const arr = arrays[i]!;
     result.set(arr, pad);
     pad += arr.length;
   }

This issue body was partially generated by patch-package.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.