国密sm2简介
国密sm2是国家密码局在2010年12月17日发布的椭圆曲线公钥密码算法,跟rsa算法一样,sm2算法也是非对称加密算法,但是sm2是一种更先进安全的算法,在我们国家商用密码体系中被用来替换rsa算法。sm2加密算法的原理可以参考文章:SM国密算法(三)-- SM2算法_sm2加密_旭日猎鹰的博客-CSDN博客
问题背景
我司众多系统采用统一认证中心实现单点登陆,之前对于网络中密码的传输采用rsa非对称加密算法,客户端加密,认证服务解密,现在公司要求加密算法更改为国密sm2算法,于是我研究了sm2算法实现的细节。
实现过程中遇到的问题
1、SM2非对称加密的结果由C1,C2,C3三部分组成。其中C1是生成随机数的计算出的椭圆曲线点,C2是密文数据,C3是SM3的摘要值。最开始的国密标准的结果是按C1C2C3顺序的,新标准的是按C1C3C2顺序存放的,而我们无论什么技术实现sm2加密,必然存在对应的模式mode(也就是C1\C2\C3的顺序),一般默认都是C1C3C2,我们需要在客户端及认证服务端约定好一致的加解密mode才能成功实现加密解密;
2、SM2密钥对一般都PEM格式和HEX格式,我们一般建议使用HEX格式,该格式公钥可以看到前缀是否以04开头(是否压缩格式),而且客户端和服务端均要使用一致的密钥对格式。
3、公钥通常以前缀04开头,后跟两个256位数字;一个用于点的x坐标,另一个用于点的y坐标。前缀04用于区分未压缩的公共密钥和以02或03开头的压缩公共密钥,即04||x||y,用此类公钥加密的密文通常也是以04开头,如果不是,则需要在密文前补04才可以正常解密。
4、go环境我本次读取公私钥文件的时候,采用的是os.open方法,本地使用go的main方法测试的时候,go读取的是gopath下的绝对路径;然后使用go项目进程启动的方式读取的时候,发现该方法读取的是当前路径下的相对路径;然后使用docker容器启动的go项目,发现该方法读取的路径既不是相对路径,也不是gopath的绝对路径,所以将读取文件的方式改为了本地变量。
问题总结
1、加密和解密端须约定加解密mode,建议是C1C3C2;
2、建议使用hex格式的密钥对;
3、如果客户端加密字符前不是04,则需要在密文前补充04才能解密;
4、建议go环境下将公私钥配置在本地变量里或者环境变量里,文件的方式无法确认访路径;