Using SM4 Symmetric Key (ECB Mode) for Encryption and Decryption

Note:

Currently in the beta phase.

For corresponding algorithm specifications, please refer to Symmetric Key Encryption/Decryption Algorithm Specifications: SM4.

Encryption

  1. Call createSymKeyGenerator to generate a symmetric key (SymKey) with SM4 as the key algorithm and a key length of 128 bits.

    For guidance on generating an SM4 symmetric key, developers can refer to the example below, along with Symmetric Key Generation and Conversion Specifications: SM4 and Random Symmetric Key Generation. Note that there may be parameter differences between the reference documents and the current example, so please pay attention to these distinctions when reading.

  2. Call createCipher with the string parameter 'SM4_128|ECB|PKCS7' to create a Cipher instance for encryption operations, specifying SM4_128 as the symmetric key type, ECB as the block mode, and PKCS7 as the padding mode.

  3. Call init to set the mode to encryption (CryptoMode.EncryptMode), specify the encryption key (SymKey), and initialize the encryption Cipher instance.

    ECB mode does not require encryption parameters, so pass None directly.

  4. Call update to update the data (plaintext).

    • For small amounts of data, you can directly call doFinal after init.
    • For large amounts of data, you can call update multiple times, i.e., perform segmented encryption/decryption.
  5. Call doFinal to obtain the encrypted data.

    Since the data has already been passed via update, pass None for the data parameter here.

Decryption

  1. Call createCipher with the string parameter 'SM4_128|ECB|PKCS7' to create a Cipher instance for decryption operations, specifying SM4_128 as the symmetric key type, ECB as the block mode, and PKCS7 as the padding mode.

  2. Call init to set the mode to decryption (CryptoMode.DecryptMode), specify the decryption key (SymKey), and initialize the decryption Cipher instance. ECB mode does not require encryption parameters, so pass None directly.

  3. Call update to update the data (ciphertext).

  4. Call doFinal to obtain the decrypted data.

Example

The synchronous method example is as follows:

import kit.CryptoArchitectureKit.*
import kit.PerformanceAnalysisKit.Hilog
import ohos.business_exception.BusinessException

// Encrypt message.
func encryptMessage(symKey: SymKey, plainText: DataBlob) {
    let cipher = createCipher('SM4_128|ECB|PKCS7')
    cipher.initialize(CryptoMode.EncryptMode, symKey, Option<ParamsSpec>.None)
    let cipherData = cipher.doFinal(plainText)
    return cipherData
}

// Decrypt message.
func decryptMessage(symKey: SymKey, cipherText: DataBlob) {
    let decoder = createCipher('SM4_128|ECB|PKCS7')
    decoder.initialize(CryptoMode.DecryptMode, symKey, Option<ParamsSpec>.None)
    let decryptData = decoder.doFinal(cipherText)
    return decryptData
}

func genSymKeyByData(symKeyData: Array<UInt8>) {
    let symKeyBlob: DataBlob = DataBlob(symKeyData)
    let sm4Generator = createSymKeyGenerator('SM4_128')
    let symKey = sm4Generator.convertKey(symKeyBlob)
    Hilog.info(0,"","convertKey success")
    return symKey
}

func test() {
    try {
        let keyData: Array<UInt8> = [7, 154, 52, 176, 4, 236, 150, 43, 237, 9, 145, 166, 141, 174, 224, 131]
        let symKey = genSymKeyByData(keyData)
        let message = "This is a test"
        let plainText: DataBlob = DataBlob(message.toArray())
        let encryptText = encryptMessage(symKey, plainText)
        let decryptText = decryptMessage(symKey, encryptText)
        if (plainText.data.toString() == decryptText.data.toString()) {
            Hilog.info(0,"",'decrypt ok')
            Hilog.info(0,"",'decrypt plainText: ' + String.fromUtf8(decryptText.data))
        } else {
            Hilog.error(0,"",'decrypt failed')
        }
    } catch (e: BusinessException) {
        Hilog.error(0,"","SM4 ${e}, error code: ${e.code}")
    }
}