sm2交换密钥,sm4加密数据
yuanjilee opened this issue · 7 comments
你好啊,冒昧打扰。
我们最近要做关于国密的加密方案,研究了很多TLS握手以及国密加密方案。但是现在仍然一头雾水的是,iOS端要怎样实现和服务端sm2交换密钥以及sm4加密数据呢?
看了你的库和 Demo 文件,发现都是本地实现的 加解密、验签以及密钥交换,这部分逻辑应该怎样与iOS结合呢?
我现在知道自签名证书可以在
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;
方法里设置为服务端根证书。
请问:
- sm2 交换密钥以及sm4加密是需要我们 iOS 端本地实现呢? 还是通过 openssl 配置 TLS 协商过程参数就可以?
- 如果本地实现或者通过 openssl 实现那么实现时机 iOS 端应该在哪个阶段呢?或者应该哪个方法呢?
十分感谢~
HTTPS通讯原理,SM2和RSA流程上没有区别。
- sm2交换密钥,客户端请求从服务器获取公钥P1,生成对称密钥K1,用P1加密K1,发送给服务器;服务器私钥解密获得对称密钥K1,客户端与服务器使用K1加密数据进行传输(仅限单向证书验证,双向类似);
- sm4加密,使用交换后的对称密钥K1进行加密即可;
- TLS协商流程是网络框架自动的,你在didReceiveChallenge中设置证书信任即可;
- 握手/断开不需要自己实现,可以仔细研究一下HTTPS原理。
很开心收到您耐心的回复~
按你所说认真研究了一遍HTTPS和 GMOBjC 封装以及头文件,产生几个疑问:
-
sm2交换密钥,客户端请求从服务器获取公钥P1,生成对称密钥K1,用P1加密K1,发送给服务器;服务器私钥解密获得对称密钥K1,客户端与服务器使用K1加密数据进行传输(仅限单向证书验证,双向类似)
sm2 交换密钥是实现与服务端握手成功的前提吗,sm2密钥交换的过程是握手阶段做相应的操作吗?就是怎么将sm2交换密钥的方法合适的时机嵌入到 iOS 项目实现连接成功。
- 服务端通过 sm2 加密的网址,iOS 端只需要设置证书信任就可以访问到吗,还是要先实现前面说的 sm2 交换密钥等阶段?
- sm4加密,只需要在sm2握手成功建立连接后,每次传输数据的时候加密数据就可以吗?
- 最后,如何将您库封装的sm2 加密、解密、验签等接口用于与服务端的 sm2 网址建立连接呢?
我可能思路有偏差,导致迟迟不知道如何握手成功访问到服务器sm2加密的网址,总是报错 The certificate for this server is invalid
或者 HANDSHAKE_FAILURE_ON_CLIENT_HELLO
。
我将网上提供的测试网址 https://demo.gmssl.cn:2443/ 证书通过 didReceiveChallenge
设置证书信任即可以访问。 但是我们服务器提供的 sm2 加密网址无法建立连接。在想是不是本地没有支持 sm2 加密的库,或者握手阶段没有成功握手。
已 star ⭐,十分感谢~
- HTTPS和GMObjC没有任何关系,服务端使用SM2类型的证书,你客户端设置信任就可以建立HTTPS连接;
- GMObjC提供的是国密相关SM2、SM3、SM4相关加解密,我说的交换密钥,是建立一条新的加密信道(如果链接已使用HTTPS,可看做已经有了一条加密信道),HTTPS安全性不高,银行类服务都需要在HTTPS加密基础上,再建立一条单独的加密信道(二次加密),对于交易密码可能还需要再次使用SM2加密(三次加密),GMObjC做的是在HTTPS加密信道基础上,建立自己的加密信道;
- SM4加密和SM2没关系,SM2是非对称加密,计算量大速度慢;SM4是对称加密,速度快,小数据量可以直接使用SM2加密,大数据量加密一般是使用非对称加密(SM2)交换对称密钥,然后使用对称加密(SM4)传输数据。
- 你提供的测试网址https://demo.gmssl.cn:2443/使用的不是SM2,而是ECDHE-RSA-AES128-GCM-SHA256;
- 最后,GMObjC和HTTPS没关系,访问失败可能是签名的证书格式不对,服务器/客户端设置问题。
感谢回复~ 第二点有点小疑问,
GMObjC提供的是国密相关SM2、SM3、SM4相关加解密,我说的交换密钥,是建立一条新的加密信道(如果链接已使用HTTPS,可看做已经有了一条加密信道),HTTPS安全性不高,银行类服务都需要在HTTPS加密基础上,再建立一条单独的加密信道(二次加密),对于交易密码可能还需要再次使用SM2加密(三次加密),GMObjC做的是在HTTPS加密信道基础上,建立自己的加密信道;
sm2建立新的加密信道是在 TLS 握手阶段建立的吗,还是在 HTTPS 的 TLS 握手完成后,再通过网络请求建立呢?
根据你第4点的回复我理解是, HTTPS 正常握手证书信任后(通过客户端设置证书信任),就可以正常访问服务端使用 SM2 类型证书的地址。至于SM2可以用来在成功访问后再在HTTPS 加密信道基础上建立新的信道。
再次感谢~
建立自己的加密信道和TLS握手没有关系,你从服务器通过HTTPS请求任何一个东西,获取到成功的响应信息,已经通过三次握手建立HTTPS连接了,至于服务端使用了什么类型的证书(RSA/SM2),不需要关心。
感谢解惑~
恍然大悟,怪不得我看的 gmssl 以及 GMObjc 的 demo 都是本地解密、解密、验签等操作,而和网络没有关系。
即是说,我打算时实现 sm2交换密钥,sm4加密数据
的需求。 只要:
- 通过
didReceiveChallenge
设置证书信任(或者还需要证书本地验签?),以便访问到服务端 SM2 签名的网址; - 访问HTTPS建立的连接请求,再通过 SM2 非对称加密,达成与服务端交换对称密钥的目的;
- 再通过交换的对称密钥进行SM4加密传输数据;
- 之后的数据都是通过SM4加密和解密完成传输。
而关于 TLS 握手阶段是不应该干涉的,所有操作实在信任证书访问到网址后,在再其基础上建立一条新的通道。
怎么感觉 SM2 加密、解密、验签、交换密钥,这些操作和 TLS 握手流程很相似 = =。
第一次接触加密、证书这块很迷惑,感谢您这几天的回复,感激不尽~
感谢帮助,问题已解决~