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();
}
}