Implementing Chinese National Cryptographic Algorithms in Java Using BouncyCastle

Chinese National Cryptographic Algorithms in Java

Chinese commercial cryptographic standards (Guomi), encompassing SM2 (asymmetric encryption), SM3 (hash), and SM4 (symmetric encryption), are mandated across various domestic government and financial sectors. Implementing these algorithms in Java applications is streamlined through the BouncyCastle library, which provides native support for the required elliptic curve and cipher operations.

Dependency Configuration

Include the BouncyCastle provider and PKIX extensions in your project. The following Maven configuration adds the necessary artifacts:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk18on</artifactId>
    <version>1.78</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk18on</artifactId>
    <version>1.78</version>
</dependency>

SM2 Encryption and Decryption Implementation

The SM2 algorithm relies on a 256-bit elliptic curve. By registering the BouncyCastle provider, standard JCE APIs can be utilized to perform key generation and cryptographic transformations. The example below demonstrates a complete workflow for initializing the SM2 curve, generating a key pair, encrypting plaintext, and reversing the process.

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import java.security.*;
import javax.crypto.Cipher;

public class Sm2CryptoHandler {
    public static void main(String[] args) throws Exception {
        // Register the cryptographic provider
        Security.addProvider(new BouncyCastleProvider());

        // Define SM2 elliptic curve parameters
        ECParameterSpec sm2CurveSpec = ECNamedCurveTable.getParameterSpec("sm2p256v1");

        // Generate asymmetric key pair
        KeyPairGenerator asymmetricKeyGen = KeyPairGenerator.getInstance("EC", "BC");
        asymmetricKeyGen.initialize(sm2CurveSpec, new SecureRandom());
        KeyPair generatedKeyPair = asymmetricKeyGen.generateKeyPair();

        String originalPayload = "Confidential information";
        byte[] payloadBytes = originalPayload.getBytes();

        // Initialize cipher for encryption
        Cipher sm2Encryptor = Cipher.getInstance("SM2", "BC");
        sm2Encryptor.init(Cipher.ENCRYPT_MODE, generatedKeyPair.getPublic());
        byte[] encryptedData = sm2Encryptor.doFinal(payloadBytes);

        System.out.println("Hex Encoded Ciphertext: " + encodeHex(encryptedData));

        // Initialize cipher for decryption
        Cipher sm2Decryptor = Cipher.getInstance("SM2", "BC");
        sm2Decryptor.init(Cipher.DECRYPT_MODE, generatedKeyPair.getPrivate());
        byte[] decryptedData = sm2Decryptor.doFinal(encryptedData);

        System.out.println("Decrypted Plaintext: " + new String(decryptedData));
    }

    private static String encodeHex(byte[] data) {
        StringBuilder hexBuilder = new StringBuilder();
        for (byte datum : data) {
            hexBuilder.append(String.format("%02x", datum));
        }
        return hexBuilder.toString();
    }
}

Tags: java Guomi SM2 BouncyCastle cryptography

Posted on Sun, 25 Oct 2026 16:04:10 +0000 by kdreg