1、版本 人员 时间 升级内容 课程目的 了解国密算法的算法原理 了解 SM2、 SM3、 SM4的算法原理 了解国密卡片相关 API 目标人员 移动金融初级开发人员 前 置课程 RSA密钥体系 DES密钥体系 基本知识 对称加密算法 SM2 非对称加密算法 SM4 摘要算法 SM3定义国 密即国家密码局认定的国产密码算法,即商用 密码,主要完成加密、解密、签名、验签、摘要等操作。常用国密算法种类 算法类型 密钥长度 输入数据要求 输出数据特征SM2 非对称加密算法 公钥 64字节,私钥 32字节。长度小于( 232-1)*32=137,438,953,440字节 (大约 1374亿多)。输出长度
2、是明文长度+96,有随机数参数,每次密文不同。SM3 摘要算法 - 无要求。 固定长度, 32字节。SM4 对称加密算法 16字节 分组长度 16字节,需要填充到 16字节整数倍。有 CBC和 ECB两种模式, CBC需要设定初始值。长度为 16字节整数倍。国密算法还有 SM1、 SM7、 SSF33、祖冲之 密码 对称加密算法, SM9非对称加密算法。国密算法与其他算法比较非对称加密算法 SM2与 RSA比较国密算法与其他算法比较SM2与 RSA算法的一些统计数据RSA密钥强度(长度) SM2密钥强度(长度) 破解时间(年)521比特 106比特 104(已破解)768比特 132比特 10
3、8(已破解)1024比特 160比特 10112048比特 210比特 1020国密算法与其他算法比较SM2与 RSA算法的一些统计 数据算法 签名速度 验签速度1024RSA 2792次 /秒 51224次 /秒2048RSA 455次 /秒 15122次 /秒256SM2 4095次 /秒 871次 /秒国密算法与其他算法比较SM4与 DES较从算法上看,国产 SM4算法在计算过程中增加非线性变换,理论上能大大提高其算法的安全性,并且由专业机构进行了密码分析,民间也对 21轮 SM4进行了差分密码分析,结论均为安全性较高。国密卡实现 API类层次图 class java.lang.Obje
4、ct class com.guomi.GMCipher class com.guomi.GMKeyBuilder class com.guomi.GMKeyPair class com.guomi.GMMessageDigest class com.guomi.GMSignature class com.guomi.GMCipherExtend class com.guomi.GMSM2KeyExchange国密卡实现的 API接口 interface javacard.security.Key interface javacard.security.SecretKey interface c
5、om.guomi.SM1Key interface com.guomi.SM4Key interface com.guomi.SM7Key interface com.guomi.SSF33Key interface javacard.security.PrivateKey interface com.guomi.SM2PrivateKey interface javacard.security.PublicKey interface com.guomi.SM2PublicKey国密卡实现的 API接口 interface com.unionpay.guomi.SM2Key interface
6、 com.guomi.SM2PrivateKey interface com.guomi.SM2PublicKey目录 算法原理 加密 解密 签名 验 签算法原理 国密 SM2规定椭圆曲线参数(固定值, 256比特) p : FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF a: FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC b: 28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDB
7、CBD414D940E93 n: FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123 gx: 32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7 gy:BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0 各个参数意义 如下椭圆曲线 方程: y2=x3+ax+b,把它定义 在 Fp上 , 要求 a,b满足: 4a3+27b20 (mod p)那么, p 、 a 、
8、b 用来确定 一条椭圆曲线(确切来说应该是有限域 Fp), G( gx, gy)为基点, n为点 G的阶 ,另外,还有一个非必要参数 h, 是椭圆曲线上所有点的个数 m与 n相除的整数 部分;加密 SM2公私玥结构、 SM2公私 玥关系P=d*G 或者 ( x, y) =d*( gx, gy),即公钥 P是基点 G的 d倍点。其中 , P为公钥,坐标表示为 (x,y), d为私钥, G为基点,坐标( gx, gy), *为离散椭圆曲线坐标系中的乘法运算。长度 举例SM2公钥 64字节,包括 x分量和 y分量6C7D9D212ED9A5B43659402F07696F7026AE2ADB874D
9、9BDC2D4DC47D883B6AEE8FC2FA7668EFD664E0876B21B1C6202551978331C59259489E5B13F941E1EA95SM2私钥 32字节 38DAF6D271322AF0AFEE399DEEF28D18B51CD8388BF78F4E78B943E7436181A4 离散域加法及多倍点图解公私玥 SM2公私玥对生成 Java CardGMKeyPair dGM_KeyPair = null;SM2PublicKey dSM2pubkey = null;SM2PrivateKey dSM2prikey = null;dGM_KeyPair =
10、new GMKeyPair(GMKeyPair.ALG_SM2_FP,GMKeyBuilder.LENGTH_SM2_FP_256);dSM2pubkey = (SM2PublicKey) GMKeyBuilder.buildKey(GMKeyBuilder.TYPE_SM2_PUBLIC,GMKeyBuilder.LENGTH_SM2_FP_256,true);dSM2prikey = (SM2PrivateKey) GMKeyBuilder.buildKey(GMKeyBuilder.TYPE_SM2_PRIVATE, GMKeyBuilder.LENGTH_SM2_FP_256,true
11、);dGM_KeyPair.genSM2KeyPair();dSM2prikey = (SM2PrivateKey) dGM_KeyPair.getPrivate();dSM2pubkey = (SM2PublicKey) dGM_KeyPair.getPublic();公私玥 SM2公私玥对 生成 Java EEAsymmetricCipherKeyPair keyPair = ecKeyPairGenerator.generateKeyPair();ECPrivateKeyParameters priKey= (ECPrivateKeyParameters) keyPair.getPriv
12、ate();ECPublicKeyParameters pubKey= (ECPublicKeyParameters) keyPair.getPublic();BigInteger biD = priKey.getD(); /私钥BigInteger biX = pubKey.getQ().getX().toBigInteger(); /公钥 X分量BigInteger biY = pubKey.getQ().getY().toBigInteger(); /公钥 Y分量加密 明文结构 SM2加密算法对明文 数据不 需要填充 。 SM2加密算法要求明文长度小于( 232-1) *32字节。注:
13、RSA算法中,明文长度要求小于模长。加密 完整密文结构字段名称 解析 长度XCoordinate 离散椭圆曲线上随机点的 x分量 32字节YCoordinate 离散椭圆曲线上随机点的 y分量 32字节HASH 哈希值, 32字节CipherText 纯密文 与明文长度一致注: SM2算法中,由于需要随机选取点参与密文计算,故相同的明文及密钥,在不同的加密过程中,密文也不相同,与 RSA算法不同。加密 加密步骤 加密 输入数据:源数据 ( M) 、 SM2公 钥 SM2Publickey(包括 公钥分量 x、 公钥分量 y)。 通过 SM2公钥加密算法, 计算完整密文。加密 SM2加密代码实现
14、 Java CardCipher dGM_Cipher = GMCipher.getInstance(GMCipher.ALG_SM2_WITH_SM3_NOPAD,false);dGM_Cipher.init(dSM2pubkey, Cipher.MODE_ENCRYPT);short reslen = dGM_Cipher.doFinal(debugdata, (short) 0,(short) debugdata.length, buf, (short) 0);加密 SM2加密代码实现 Java EESM2 sm2 = SM2.getInstance();Cipher cipher =
15、new Cipher();ECPoint userKey = sm2.getUserKey(x, y);/ 随机生成公钥分量, c1.x、 c1.y。 cipher.encrypt(data)ECPoint c1 = cipher.init_enc(sm2, userKey);byte xy = c1.getEncoded();byte thash = necipher.doFinal(thash);/ 计算 HASHw byte32;System.out.println(“allciphertext=“+ Utils.toHexStringNoBlank(xy).substring(2, 1
16、30)+ Utils.toHexStringNoBlank(thash)+ Utils.toHexStringNoBlank(data);解密 解密步骤 输入数据 : 密文( C) 、 SM2私 钥 SM2prikey。 计算 出 明文 M,并校验 HASH。解密 解密代码实现 Java CardCipher dGM_Cipher = GMCipher.getInstance(GMCipher.ALG_SM2_WITH_SM3_NOPAD,false);dGM_Cipher.init(dSM2prikey, Cipher.MODE_ENCRYPT);Short reslen = dGM_Cip
17、her.doFinal(buf, ISO7816.OFFSET_CDATA,reslen, buf,(short) 0);解密 解密代码实现 Java EE/分解密文,得到随机取的点 x、 y分量, hash值,纯密文。/椭圆曲线上随机取的点 pointECPoint point = SM2.getInstance().ecc_curve.decodePoint(c1);cipher.init_dec(priKey, point);cipher.decrypt(pureciphertext);cipher.doFinal(c3_);/使用解密的明文计算的 hash, C3_.String C3
18、_ = Utils.toHexStringNoBlank(c3_);/密文中恢复的 hash,C3.String C3 = Utils.toHexStringNoBlank(c3);if (!C3_.equals(C3) System.out.println(“未通过 C3校验,解密失败 nC3=“ +C3 + “nC3_=“ + C3_);return;签名 私钥签名值结构字段 解释 长度R 签名值的第一部分 32字节S 签名值的第二部分 32字节签名 签名步骤 签名输入数据:源数据 ( M) 、用户 ID( ID) 、公钥参数 x( x)、公钥参数 y( y)、私钥( privatekey
19、); 通过 SM3算法计算 杂凑 Za, 输入数据: ID的比特长度 (2bytes)+ID+a+b+gx+gy+x+y; 其中 , a、 b、 gx、 gy为椭圆曲线参数,固定值。 通过 SM2签名 算法进行签名得到 签名值, 输入数据: Za+M +privatekey;签名 签名代码实现 Java CardSignature dGM_Signature = GMSignature.getInstance(GMSignature.ALG_SM2_SM3_256,false);GMCipherExtend.getZa(ID,(short)0,(short)ID.length,dSM2pubkey,ZA,(short)0,GMCipherExtend.PARAM_FP_256);dGM_Signature.init(dSM2prikey,dGM_Signature.MODE_SIGN);short reslen = dGM_Signature.sign(buf,(short)0,(short)(ZA.length + sourcedatalen),buf,(short)0);