gm-crypto

repository·main·Indexed 42 days ago

https://github.com/byte-fe/gm-crypto

A pure JavaScript implementation of Chinese national standard (GM/T) cryptographic algorithms, including SM2 (asymmetric), SM3 (hash), and SM4 (symmetric). Version 0.1.12 is compatible with both Node.js and browser environments.

Tokens
4.2K
Snippets
12
Records
22
Agent score
52%

What's inside gm-crypto

  1. Install gm-crypto

    main

    You can install gm-crypto using npm or yarn. This library provides a pure JavaScript implementation of GM/T series (SM2, SM3, SM4) cryptographic algorithms compatible with both Node.js and browsers.

    $ npm install gm-crypto
    $ yarn add gm-crypto
  2. SM4 Encryption Modes

    main

    The SM4 implementation supports two block cipher modes:

    • ECB (Electronic Codebook): Each block is encrypted independently.
    • CBC (Cipher Block Chaining): Each block of plaintext is XORed with the previous ciphertext block before being encrypted. This mode requires an Initialization Vector (iv).
  3. Use SM3 for cryptographic hashing

    main

    SM3 is a cryptographic hash algorithm. Use SM3.digest(data, [inputEncoding], [outputEncoding]) to generate digests. If encoding parameters are omitted, they default to 'utf8' for input and 'hex' for output.

    const { SM3 } = require('gm-crypto')
    
    console.log(SM3.digest('abc'))
    console.log(SM3.digest('YWJj', 'base64'))
    console.log(SM3.digest('616263', 'hex', 'base64'))
  4. Use SM2 for public key cryptography

    main

    SM2 is a public key cryptographic algorithm based on elliptic curves. You can generate key pairs, encrypt data using a public key, and decrypt data using a private key.

    When using SM2.encrypt and SM2.decrypt, you can specify inputEncoding and outputEncoding to handle different data formats (e.g., 'utf8', 'base64', 'hex').

    const { SM2 } = require('gm-crypto')
    
    const { publicKey, privateKey } = SM2.generateKeyPair()
    const originalData = 'SM2 椭圆曲线公钥密码算法'
    
    const encryptedData = SM2.encrypt(originalData, publicKey, {
      inputEncoding: 'utf8',
      outputEncoding: 'base64'
    })
    
    const decryptedData = SM2.decrypt(encryptedData, privateKey, {
      inputEncoding: 'base64',
      outputEncoding: 'utf8'
    })
  5. Use SM4 for symmetric block cipher encryption

    main

    SM4 is a block cipher algorithm. It supports multiple modes of operation, including:

    • ECB: Electronic Codebook
    • CBC: Cipher Block Chaining

    To use CBC mode, you must provide an iv (Initialization Vector). The key should be a string of 32 hexadecimal digits. You can specify inputEncoding, outputEncoding, mode, and iv in the options object.

    const { SM4 } = require('gm-crypto')
    
    const key = '0123456789abcdeffedcba9876543210' // Any string of 32 hexadecimal digits
    const originalData = 'SM4 国标对称加密'
    
    let encryptedData, decryptedData
    
    // ECB mode
    encryptedData = SM4.encrypt(originalData, key, {
      inputEncoding: 'utf8',
      outputEncoding: 'base64'
    })
    decryptedData = SM4.decrypt(encryptedData, key, {
      inputEncoding: 'base64',
      outputEncoding: 'utf8'
    })
    
    // CBC mode
    const iv = '0123456789abcdeffedcba9876543210' // Initialization vector (32 hex digits)
    encryptedData = SM4.encrypt(originalData, key, {
      iv: iv,
      mode: SM4.constants.CBC,
      inputEncoding: 'utf8',
      outputEncoding: 'hex'
    })
    decryptedData = SM4.decrypt(encryptedData, key, {
      iv: iv,
      mode: SM4.constants.CBC,
      inputEncoding: 'hex',
      outputEncoding: 'utf8'
    })
  6. Decrypt data with SM2

    main

    Use decrypt(data, privateKey, options) to decrypt an SM2 ciphertext using an SM2 private key.

    Parameters:

    • data: The ciphertext to decrypt. Can be a string, Buffer, or ArrayBuffer.
    • privateKey: The recipient's SM2 private key as a hex string.
    • options: An optional configuration object:
      • mode: Must match the mode used during encryption (C1C2C3 or C1C3C2). Default is C1C3C2.
      • inputEncoding: The encoding of the input data if it is a string.
      • outputEncoding: If provided, the decrypted plaintext is returned as a string with this encoding. If omitted, it returns an ArrayBuffer.
      • pc: A boolean. If true, the function expects the ciphertext to be prefixed with 04.

    Returns: The decrypted plaintext as an ArrayBuffer (default) or a string (if outputEncoding is specified). If decryption or integrity verification fails, it returns an empty ArrayBuffer (or empty string if outputEncoding is set).

    import { decrypt } from 'gm-crypto/sm2';
    
    const privateKey = '...'; // Your SM2 private key
    const ciphertext = '...'; // The ciphertext from encrypt()
    
    // Decrypting to an ArrayBuffer
    const plaintextBuffer = decrypt(ciphertext, privateKey, { mode: 'C1C2C3' });
    
    // Decrypting to a UTF-8 string
    const plaintext = decrypt(ciphertext, privateKey, { 
      mode: 'C1C2C3', 
      outputEncoding: 'utf8' 
    });
  7. Encrypt data with SM2

    main

    Use encrypt(data, publicKey, options) to encrypt a message using an SM2 public key.

    Parameters:

    • data: The plaintext to encrypt. Can be a string, Buffer, or ArrayBuffer.
    • publicKey: The recipient's SM2 public key as a hex string.
    • options: An optional configuration object:
      • mode: The concatenation order of the ciphertext components. Supported values: C1C2C3 or C1C3C2 (default is C1C3C2).
      • inputEncoding: The encoding of the input data if it is a string (default: 'utf8').
      • outputEncoding: If provided, the function returns a string with this encoding. If omitted, it returns an ArrayBuffer.
      • pc: A boolean. If true, the output ciphertext is prefixed with 04.

    Returns: An ArrayBuffer (default) or a string (if outputEncoding is specified).

    import { encrypt } from 'gm-crypto/sm2';
    
    const publicKey = '04...'; // Your SM2 public key
    const data = 'Hello SM2';
    
    // Encrypting to an ArrayBuffer
    const ciphertext = encrypt(data, publicKey, { mode: 'C1C2C3' });
    
    // Encrypting to a hex string
    const ciphertextHex = encrypt(data, publicKey, { 
      mode: 'C1C2C3', 
      outputEncoding: 'hex' 
    });
  8. Encrypt data using SM4

    main

    Use the encrypt function to perform SM4 encryption.

    Parameters:

    • data: The plaintext to encrypt. Can be a string, Buffer, or ArrayBuffer.
    • key: A 32-character hexadecimal string representing the 128-bit key.
    • options: An object containing:
      • mode: Either constants.ECB or constants.CBC.
      • iv: A 32-character hexadecimal string representing the Initialization Vector (required if mode is CBC).
      • inputEncoding: The encoding of the input data if it is a string (defaults to 'utf8').
      • outputEncoding: If provided, the function returns the ciphertext as a string in this encoding. If omitted, it returns an ArrayBuffer.
    import { encrypt, constants } from 'gm-crypto/src/lib/sm4';
    
    const key = '0123456789abcdef0123456789abcdef';
    const iv = 'abcdef0123456789abcdef0123456789';
    const data = 'hello world';
    
    // CBC Mode (requires IV)
    const ciphertext = encrypt(data, key, {
      mode: constants.CBC,
      iv: iv,
      outputEncoding: 'hex'
    });
  9. Decrypt data using SM4

    main

    Use the decrypt function to decrypt SM4 ciphertext.

    Parameters:

    • data: The ciphertext to decrypt. Can be a string, Buffer, or ArrayBuffer.
    • key: A 32-character hexadecimal string representing the 128-bit key.
    • options: An object containing:
      • mode: Either constants.ECB or constants.CBC.
      • iv: A 32-character hexadecimal string representing the Initialization Vector (required if mode is CBC).
      • inputEncoding: The encoding of the input data if it is a string.
      • outputEncoding: If provided, the function returns the decrypted plaintext as a string in this encoding. If omitted, it returns an ArrayBuffer.
    import { decrypt, constants } from 'gm-crypto/src/lib/sm4';
    
    const key = '0123456789abcdef0123456789abcdef';
    const iv = 'abcdef0123456789abcdef0123456789';
    const ciphertext = '...'; // hex string
    
    const plaintext = decrypt(ciphertext, key, {
      mode: constants.CBC,
      iv: iv,
      inputEncoding: 'hex',
      outputEncoding: 'utf8'
    });