Android平台使用大宝CA版本JCE完成SM2、SM3、SM4国密算法、密钥、国密数字证书的详细说明

系统要求
Android 5.0(API 21)及以上 

功能介绍

  1. SM2密钥对的生成功能
  2. SM2密钥对的还原功能
  3. SM2算法的非对称加解密功能
  4. SM2算法的签名/验证功能
  5. SM3算法的摘要功能
  6. SM4算法的对称加解密功能
  7. 大宝CA版本Keystore文件(DCKS文件)存储SM2密钥对和国密数字证书的功能

Android调用JCE的主要代码

package com.doubleca.android.sample.gmjce;

import com.doubleca.b146.c16.util.encoders.Base64;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Enumeration;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import doubleca.security.provider.DoubleCA;
import doubleca.security.provider.jdk7.sm4.SM4KeySpec;

public class GmTest
{
    private static final String SIGNATURE_KEY_ALGORITHM = "SM2";
    private static final String SIGNATURE_ALGORITHM = "SM3withSM2";
    private static final int SIGNATURE_KEY_SIZE = 256;
    private static final String DIGEST_ALGORITHM = "SM3";
    private static final String CIPHER_SM4_KEY_ALGORITHM = "SM4";
    //	private static final String CIPHER_SM4_ALGORITHM = "SM4/ECB/PKCS5Padding";
    private static final String CIPHER_SM4_ALGORITHM = "SM4/CBC/PKCS5Padding";
    // private static final String CIPHER_SM4_ALGORITHM = "SM4/ECB/NOPadding";
    // private static final String CIPHER_SM4_ALGORITHM = "SM4/CBC/NOPadding";
    private static final String CIPHER_SM2_ALGORITHM = "SM2/NONE/NOPadding";

    public static SecretKey TestSM4Cipher()
    {
        try
        {
            String plainText1 = "软件(库)授权与防复制、防盗版,全平台支持:";
            String plainText2 = "https://www.PPLIC.com ";
            byte[] plain1 = plainText1.getBytes();
            byte[] plain2 = plainText2.getBytes();
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(CIPHER_SM4_KEY_ALGORITHM, DoubleCA.PROVIDER_NAME);
            SM4KeySpec keySpec = new SM4KeySpec("1234567812345678".getBytes("utf-8"));
            IvParameterSpec iv = new IvParameterSpec("1234567812345678".getBytes());
            SecretKey key = keyFactory.generateSecret(keySpec);
            BigInteger keyBuffer = new BigInteger(1, key.getEncoded());
            System.out.println("SM4 Key :" + keyBuffer.toString(16).toUpperCase());

            //			KeyGenerator kgen = KeyGenerator.getInstance("OID.1.2.156.10197.1.104");
            //			KeyGenerator kgen = KeyGenerator.getInstance("1.2.156.10197.1.104");
            //			KeyGenerator kgen = KeyGenerator.getInstance("SMS4");

            KeyGenerator kgen = KeyGenerator.getInstance(CIPHER_SM4_KEY_ALGORITHM);
            kgen.init(128, new SecureRandom("12345678".getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec sm4keySpec = new SecretKeySpec(enCodeFormat, CIPHER_SM4_KEY_ALGORITHM);
            keyBuffer = new BigInteger(1, sm4keySpec.getEncoded());
            System.out.println("SM4KeySpec :" + keyBuffer.toString(16).toUpperCase());
            Cipher cipher = Cipher.getInstance(CIPHER_SM4_ALGORITHM);// 创建密码器
            //			cipher.init(Cipher.ENCRYPT_MODE, sm4keySpec);// 初始化
            cipher.init(Cipher.ENCRYPT_MODE, sm4keySpec, iv);// 初始化
            byte[] sm4ResultBuffer = new byte[cipher.getOutputSize(plain1.length + plain2.length)];
            int bufferLen = cipher.update(plain1, 0, plain1.length, sm4ResultBuffer, 0);
            bufferLen += cipher.update(plain2, 0, plain2.length, sm4ResultBuffer, bufferLen);
            bufferLen += cipher.doFinal(sm4ResultBuffer, bufferLen);
            byte[] result = new byte[bufferLen];
            System.arraycopy(sm4ResultBuffer, 0, result, 0, sm4ResultBuffer.length);
            BigInteger buffer = new BigInteger(1, result);
            System.out.println("原文1:" + plainText1);
            System.out.println("原文2:" + plainText2);
            System.out.println("密文:" + new String(Base64.encode(result)));
            //			cipher.init(Cipher.DECRYPT_MODE, sm4keySpec);// 初始化
            cipher.init(Cipher.DECRYPT_MODE, sm4keySpec, iv);// 初始化
            sm4ResultBuffer = new byte[cipher.getOutputSize(result.length)];
            bufferLen = cipher.update(result, 0, result.length / 2, sm4ResultBuffer, 0);
            bufferLen += cipher.update(result, result.length / 2, result.length - (result.length / 2), sm4ResultBuffer, bufferLen);
            bufferLen += cipher.doFinal(sm4ResultBuffer, bufferLen);
            result = new byte[bufferLen];
            System.arraycopy(sm4ResultBuffer, 0, result, 0, result.length);
            System.out.println("原文:" + new String(result));
            return key;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return null;
        }
    }

    public static boolean TestSM3Digest()
    {
        try
        {
            MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM);
            byte[] result;
            md.update("大宝CA 国密SSL(v1.1)算法库:https://www.DoubleCA.com ".getBytes());
            // byte[] result = md.digest("1234512345".getBytes());
            result = md.digest();
            System.out.println(md.getAlgorithm() + " MessageDigest : " + new BigInteger(1, result).toString(16).toUpperCase());
            return true;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return false;
        }
    }

    public static boolean TestSM2Signature(KeyPair key) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException
    {
        String content = "大宝CA 国密SSL(v1.1)Tomcat:https://www.DoubleCA.com ";
        System.out.println("原文:" + content);
        java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(key.getPrivate());
        signature.update(content.getBytes());
        byte[] signValue = signature.sign();
        System.out.println("签名值:" + new String(Base64.encode(signValue)));
        signature.initVerify(key.getPublic());
        signature.update(content.getBytes());
        boolean result = signature.verify(signValue);
        System.out.println("签名验证结果 :" + result);
        return result;
    }

    public static boolean TestSM2AsymmetricCipher(KeyPair key)
    {
        try
        {
            Cipher cipher = Cipher.getInstance(CIPHER_SM2_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key.getPublic());
            String plainText = "软件(库)授权与防复制:https://www.PPLIC.com ";
            System.out.println("原文:" + plainText);
            cipher.update(plainText.getBytes());
            byte[] cipherByte = cipher.doFinal();
            System.out.println("密文:" + new String(Base64.encode(cipherByte)));
            cipher.init(Cipher.DECRYPT_MODE, key.getPrivate());
            byte[] plainByte = cipher.doFinal(cipherByte);
            System.out.println("原文:" + new String(plainByte));
            return true;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return false;
        }
    }

    public static KeyPair TestSM2KeyPairGenerator() throws Exception
    {
        // 生成密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(SIGNATURE_KEY_ALGORITHM);
        keyGen.initialize(SIGNATURE_KEY_SIZE);
        KeyPair key = keyGen.generateKeyPair();
        PublicKey publicKey = key.getPublic();
        BigInteger a = new BigInteger(1, key.getPrivate().getEncoded());
        BigInteger b = new BigInteger(1, publicKey.getEncoded());
        System.out.println(keyGen.getAlgorithm() + " KeyPairGenerator publickey : " + b.toString(16));
        System.out.println(keyGen.getAlgorithm() + " KeyPairGenerator privatekey : " + a.toString(16));
        return key;
    }

    public static boolean TestSM2KeyFactory(byte[] publicKeyByteArray, byte[] privateKeyByteArray)
    {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByteArray);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyByteArray);
        try
        {
            KeyFactory factory = KeyFactory.getInstance(SIGNATURE_KEY_ALGORITHM);
            PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);
            PrivateKey privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);
            BigInteger b = new BigInteger(1, publicKey.getEncoded());
            BigInteger a = new BigInteger(1, privateKey.getEncoded());
            System.out.println(factory.getAlgorithm() + " KeyFactory public key : " + b.toString(16));
            System.out.println(factory.getAlgorithm() + " KeyFactory private key : " + a.toString(16));
            return true;
        }
        catch (NoSuchAlgorithmException | InvalidKeySpecException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
    }

    public static boolean TestReadDCKS(InputStream fis, String password)
    {
        KeyStore ks = null;
        if (fis != null)
        {
            try
            {
                ks = KeyStore.getInstance("DCKS");
                ks.load(fis, password.toCharArray());
                Enumeration e = ks.aliases();
                while (e.hasMoreElements())
                {
                    String alias = (String) e.nextElement();
                    System.out.println("alias : " + alias);
                    if (ks.isKeyEntry(alias))
                    {
                        // key
                        Key key = ks.getKey(alias, password.toCharArray());
                        System.out.println("Key Type : " + key.getFormat());
                        System.out.println("Key Algorithm : " + key.getAlgorithm());
                        if (key instanceof PrivateKey)
                        {
                            System.out.println("PrivateKey Value : " + new BigInteger(1, key.getEncoded()));
                            Certificate cert = ks.getCertificate(alias);
                            System.out.println("Certificate Value : " + cert);
                        }
                        else if (key instanceof SecretKey)
                        {
                            System.out.println("Key Value : " + new BigInteger(1, key.getEncoded()));
                        }
                        else
                        {
                            System.out.println("unknown key type...");
                        }
                    }
                    else if (ks.isCertificateEntry(alias))
                    {
                        // cert
                        System.out.println("CertificateEntry : " + ks.getCertificate(alias));
                    }
                    else
                    {
                        // trusted cert
                        System.out.println("TrustedEntry : " + ks.getCertificate(alias));
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
                return false;
            }
        }
        return false;
    }
    public static boolean TestCreateDCKS(String fileName, String password, KeyPair sm2Key, SecretKey sm4key)
    {
        KeyStore ks = null;
        File keyStoreFile = new File(fileName);
        try
        {
            ks = KeyStore.getInstance("DCKS");
            ks.load(null, password.toCharArray());
            FileOutputStream fos = new FileOutputStream(keyStoreFile);
            KeyStore.PasswordProtection p = new KeyStore.PasswordProtection(password.toCharArray());

            if (sm2Key != null)
            {
                CertificateFactory cf = CertificateFactory.getInstance("X.509", DoubleCA.PROVIDER_NAME);
                X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream("resources/sm2cert.cer"));
                X509Certificate[] serverChain = new X509Certificate[] {cert};
                ks.setEntry("DoubleCA-SM2", new KeyStore.PrivateKeyEntry(sm2Key.getPrivate(), serverChain), p);
            }
            if (sm4key != null)
            {
                KeyStore.Entry entry = new KeyStore.SecretKeyEntry(sm4key);
                ks.setEntry("DoubleCA-SM4", entry, p);
            }
            ks.store(fos, password.toCharArray());
            fos.close();
            return true;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return false;
        }
    }

}

Android平台运行结果

Android控制台输出结果

I/System.out:  ------ http://www.DoubleCA.com ---- 大宝CA ------ 
     -------       Watchdata & DoubleCA       ------- 
I/System.out: TestSM2KeyPairGenerator
I/System.out: SM2 KeyPairGenerator publickey : 3059301306072a8648ce3d020106082a811ccf5501822d034200040286345d8b9df6a2c775ecba32bef0847c3ef5e64881a64481c9567227b57f3cdd2f9685d8f55f478124db5cda0d8bb010e8e0002e2021e1e884cfdd74fd0c20
    SM2 KeyPairGenerator privatekey : 30818b020100301306072a8648ce3d020106082a811ccf5501822d0471306f02010104207dd3196abef53a19ab869687bddf6bdba86b25eff75ba60af632c6041fe15ba3a0020500a144034200040286345d8b9df6a2c775ecba32bef0847c3ef5e64881a64481c9567227b57f3cdd2f9685d8f55f478124db5cda0d8bb010e8e0002e2021e1e884cfdd74fd0c20
    TestSM2KeyFactory
I/System.out: SM2 KeyFactory public key : 3059301306072a8648ce3d020106082a811ccf5501822d034200040286345d8b9df6a2c775ecba32bef0847c3ef5e64881a64481c9567227b57f3cdd2f9685d8f55f478124db5cda0d8bb010e8e0002e2021e1e884cfdd74fd0c20
I/System.out: SM2 KeyFactory private key : 308193020100301306072a8648ce3d020106082a811ccf5501822d0479307702010104207dd3196abef53a19ab869687bddf6bdba86b25eff75ba60af632c6041fe15ba3a00a06082a811ccf5501822da144034200040286345d8b9df6a2c775ecba32bef0847c3ef5e64881a64481c9567227b57f3cdd2f9685d8f55f478124db5cda0d8bb010e8e0002e2021e1e884cfdd74fd0c20
    TestSM3Digest
I/System.out: SM3 MessageDigest : 6B2CB90C78B51E714E1BEB8290A58C75CDAF3DFDB5DBBCCF9CE247DEFB4A1308
    TestSM4Cipher
I/System.out: SM4 Key :31323334353637383132333435363738
I/System.out: SM4KeySpec :EBDD39999C2358607CB7EF92F7C3A916
I/System.out: 原文1:软件(库)授权与防复制、防盗版,全平台支持:
I/System.out: 原文2:https://www.PPLIC.com 
    密文:1lc6FUKGS+1ftIGiFDDfFdkZOEi2i1XUFsvZZnRvp8LzW6caJfJ5GBgn2d2sBVHdQaMI+IJBiX1i8EwltTbyYSkX4p6Qg1sKtoeYCEXpFk8pJK3HwwgjONpOet7Au4SG
    原文:软件(库)授权与防复制、防盗版,全平台支持:https://www.PPLIC.com 
I/System.out: TestSM2AsymmetricCipher
    原文:软件(库)授权与防复制:https://www.PPLIC.com 
I/System.out: 密文:MIGjAiEA1Gh/7xfFIPFRPh3MP5MZ2JQNUvNV77SyqfbbX/t09cECICbF0A20CfVcY4ikuKZUUOIRwEoTj1Jgs9JCM0UGF7xLBCCxnItl0TAl9MfjmvvDT+UWCGuj+Zw6hJFxBmbJM4BJVAQ6oasCBpiSqvRe7uPwLBEuQ+fC9E1aNp3tzkrmDTADMMzHXP/rF3riEKd5qA5Ims7xbysXU6ZhXEwHyA==
I/System.out: 原文:软件(库)授权与防复制:https://www.PPLIC.com 
I/System.out: TestSM2Signature
    原文:大宝CA 国密SSL(v1.1)Tomcat:https://www.DoubleCA.com 
I/System.out: 签名值:MEQCICGazQkd/G6YQU0Y3kSXeqGYeyMIKnCjGMniZSvPlX47AiAjvlGAtrTvICI6BRe0NJHIRkyPjUAqbY1aIYgkUwjg8A==
I/System.out: 签名验证结果 :true
    TestReadDCKS
I/System.out: alias : cn=客户端国密ssl测试证书,e=service@doubleca.com,ou=测试,c=cn
I/System.out: Key Type : PKCS#8
    Key Algorithm : SM2
    PrivateKey Value : 3362573024668345226776108319589020300863179425454674990711302050875880756269172595625955136383413772263809955023913419607219872954724110972477389615746516786534283224853253730182499166945837
I/System.out: Certificate Value :   [0]         Version: 3
             SerialNumber: 54562568ffab8b47d4b8d0b5449d7bad
                 IssuerDN: C=CN,ST=BEIJING,O=www.DoubleCA.com,CN=DoubleCA.com TEST01 CA SM2
               Start Date: Sun Feb 17 14:56:11 GMT+00:00 2019
               Final Date: Mon Feb 17 14:56:11 GMT+00:00 2020
                SubjectDN: C=CN,OU=测试,E=service@doubleca.com,CN=客户端国密SSL测试证书
               Public Key: DoubleCA SM2 public key, 256 bits
      public x coord: 65215284186172334808088917997998955419701388929546536492749289805550975234211
      public y coord: 69132452507784084332570142049583404962143056570916935248218677493657120037057
      parameters: com.doubleca.security.spec.SM2ParameterSpec@c8e4f88
      Signature Algorithm: SM3WithSM2Encryption
                Signature: 3045022100f8e5c5c0d511e11c0a78d33195796c
                           821bed0a76a87d1c76e7cf008e374fed3a02200b
                           4242535a2a89cbebc2c0e72a3deb3680cb4014eb
                           c44921f7d4b502035eb5cb
           Extensions: 
                           critical(false) 2.5.29.37 value = DER Sequence
        ObjectIdentifier(1.3.6.1.5.5.7.3.1)
        ObjectIdentifier(1.3.6.1.5.5.7.3.2)
                           critical(false) NetscapeCertType: 0xc0
                           critical(false) 2.5.29.17 value = DER Sequence
        Tagged [2] IMPLICIT 
            DER Octet String[16] 
        Tagged [7] IMPLICIT 
            DER Octet String[4] 
                           critical(false) 2.5.29.14 value = DER Octet String[20] 
                           critical(false) KeyUsage: 0xf8
                           critical(false) 2.5.29.31 value = DER Sequence
I/System.out:     DER Sequence
            Tagged [0]
                Tagged [0]
                    Tagged [6] IMPLICIT 
                        DER Octet String[58] 
    alias : cn=doubleca.com root ca sm2,o=www.doubleca.com,st=beijing,c=cn
I/System.out: CertificateEntry :   [0]         Version: 3
             SerialNumber: 283909e859da6101c286b6d79fc61375
                 IssuerDN: C=CN,ST=BEIJING,O=www.DoubleCA.com,CN=DoubleCA.com ROOT CA SM2
               Start Date: Tue Feb 20 15:29:34 GMT+00:00 2018
               Final Date: Thu Feb 20 15:29:34 GMT+00:00 2048
                SubjectDN: C=CN,ST=BEIJING,O=www.DoubleCA.com,CN=DoubleCA.com ROOT CA SM2
               Public Key: DoubleCA SM2 public key, 256 bits
      public x coord: 63567973297631315756188461682412948032663271290975609239585908391063398144336
      public y coord: 94293482803615337477639920676818685203833495478712519677665296690516936973566
      parameters: com.doubleca.security.spec.SM2ParameterSpec@c8e4f88
      Signature Algorithm: SM3WithSM2Encryption
                Signature: 3046022100ccdc6e27d819f86166bee2d011b422
                           da247b7325a9ebdd0372ed6cdbf0333102022100
                           a5ff2eb05a0154f1475d4facc9056f857e541065
                           0586acc21d2decbf2cbab88b
           Extensions: 
                           critical(false) 2.5.29.35 value = DER Sequence
        Tagged [0] IMPLICIT 
            DER Octet String[20] 
                           critical(false) 2.5.29.14 value = DER Octet String[20] 
                           critical(false) KeyUsage: 0x6
I/System.out:                        critical(true) BasicConstraints: isCa(true)
    alias : cn=doubleca.com test01 ca sm2,o=www.doubleca.com,st=beijing,c=cn
    CertificateEntry :   [0]         Version: 3
             SerialNumber: 366fab022c0d7e8ae6801e445c865086
I/System.out:              IssuerDN: C=CN,ST=BEIJING,O=www.DoubleCA.com,CN=DoubleCA.com ROOT CA SM2
               Start Date: Tue Feb 20 15:49:22 GMT+00:00 2018
               Final Date: Sat Feb 20 15:49:22 GMT+00:00 2038
                SubjectDN: C=CN,ST=BEIJING,O=www.DoubleCA.com,CN=DoubleCA.com TEST01 CA SM2
               Public Key: DoubleCA SM2 public key, 256 bits
      public x coord: 60595735744867038260274389887165641798371778284629229257466280556093420133086
      public y coord: 59336568717492114170665705208274640089654406332240289026426787465310346749757
      parameters: com.doubleca.security.spec.SM2ParameterSpec@c8e4f88
      Signature Algorithm: SM3WithSM2Encryption
                Signature: 3045022100fbea4e34a1eb2175f559eee65401a8
                           66c3e44bb45b54533220bef12a1cb7d0af022049
                           3ba8f11225343982e484951d98c33f1ea89d952c
                           2a1ac9c5ab4cd0e2b8deb2
           Extensions: 
                           critical(false) 2.5.29.31 value = DER Sequence
        DER Sequence
            Tagged [0]
                Tagged [0]
                    Tagged [6] IMPLICIT 
                        DER Octet String[56] 
                           critical(false) KeyUsage: 0xfe
                           critical(false) 2.5.29.14 value = DER Octet String[20] 
                           critical(false) BasicConstraints: isCa(true), pathLenConstraint = 3
     finish.

示例代码下载地址:https://download.csdn.net/download/upset_ming/11761957

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值