muzipiao/GMObjC

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;

方法里设置为服务端根证书。

请问:

  1. sm2 交换密钥以及sm4加密是需要我们 iOS 端本地实现呢? 还是通过 openssl 配置 TLS 协商过程参数就可以?
  2. 如果本地实现或者通过 openssl 实现那么实现时机 iOS 端应该在哪个阶段呢?或者应该哪个方法呢?

十分感谢~

HTTPS通讯原理,SM2和RSA流程上没有区别。

  1. sm2交换密钥,客户端请求从服务器获取公钥P1,生成对称密钥K1,用P1加密K1,发送给服务器;服务器私钥解密获得对称密钥K1,客户端与服务器使用K1加密数据进行传输(仅限单向证书验证,双向类似);
  2. sm4加密,使用交换后的对称密钥K1进行加密即可;
  3. TLS协商流程是网络框架自动的,你在didReceiveChallenge中设置证书信任即可;
  4. 握手/断开不需要自己实现,可以仔细研究一下HTTPS原理。

很开心收到您耐心的回复~

按你所说认真研究了一遍HTTPS和 GMOBjC 封装以及头文件,产生几个疑问:

  1. sm2交换密钥,客户端请求从服务器获取公钥P1,生成对称密钥K1,用P1加密K1,发送给服务器;服务器私钥解密获得对称密钥K1,客户端与服务器使用K1加密数据进行传输(仅限单向证书验证,双向类似)

sm2 交换密钥是实现与服务端握手成功的前提吗,sm2密钥交换的过程是握手阶段做相应的操作吗?就是怎么将sm2交换密钥的方法合适的时机嵌入到 iOS 项目实现连接成功。

  1. 服务端通过 sm2 加密的网址,iOS 端只需要设置证书信任就可以访问到吗,还是要先实现前面说的 sm2 交换密钥等阶段?
  2. sm4加密,只需要在sm2握手成功建立连接后,每次传输数据的时候加密数据就可以吗?
  3. 最后,如何将您库封装的sm2 加密、解密、验签等接口用于与服务端的 sm2 网址建立连接呢?

我可能思路有偏差,导致迟迟不知道如何握手成功访问到服务器sm2加密的网址,总是报错 The certificate for this server is invalid 或者 HANDSHAKE_FAILURE_ON_CLIENT_HELLO

我将网上提供的测试网址 https://demo.gmssl.cn:2443/ 证书通过 didReceiveChallenge 设置证书信任即可以访问。 但是我们服务器提供的 sm2 加密网址无法建立连接。在想是不是本地没有支持 sm2 加密的库,或者握手阶段没有成功握手。

已 star ⭐,十分感谢~

  1. HTTPS和GMObjC没有任何关系,服务端使用SM2类型的证书,你客户端设置信任就可以建立HTTPS连接;
  2. GMObjC提供的是国密相关SM2、SM3、SM4相关加解密,我说的交换密钥,是建立一条新的加密信道(如果链接已使用HTTPS,可看做已经有了一条加密信道),HTTPS安全性不高,银行类服务都需要在HTTPS加密基础上,再建立一条单独的加密信道(二次加密),对于交易密码可能还需要再次使用SM2加密(三次加密),GMObjC做的是在HTTPS加密信道基础上,建立自己的加密信道;
  3. SM4加密和SM2没关系,SM2是非对称加密,计算量大速度慢;SM4是对称加密,速度快,小数据量可以直接使用SM2加密,大数据量加密一般是使用非对称加密(SM2)交换对称密钥,然后使用对称加密(SM4)传输数据。
  4. 你提供的测试网址https://demo.gmssl.cn:2443/使用的不是SM2,而是ECDHE-RSA-AES128-GCM-SHA256;
  5. 最后,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加密数据 的需求。 只要:

  1. 通过 didReceiveChallenge 设置证书信任(或者还需要证书本地验签?),以便访问到服务端 SM2 签名的网址;
  2. 访问HTTPS建立的连接请求,再通过 SM2 非对称加密,达成与服务端交换对称密钥的目的;
  3. 再通过交换的对称密钥进行SM4加密传输数据;
  4. 之后的数据都是通过SM4加密和解密完成传输。

而关于 TLS 握手阶段是不应该干涉的,所有操作实在信任证书访问到网址后,在再其基础上建立一条新的通道。
怎么感觉 SM2 加密、解密、验签、交换密钥,这些操作和 TLS 握手流程很相似 = =。

第一次接触加密、证书这块很迷惑,感谢您这几天的回复,感激不尽~

感谢帮助,问题已解决~