安全键盘
从基础库2.18.0开始支持
很多小程序业务都需要输入一些敏感信息,比如密码、身份证、手机号码等,不专业的做法是使用明文提交给业务后台,在网络传输和传输过程中非常容易泄露。不符合合规要求。还有一些改进的做法是使用敏感信息的加密,例如将明文密码加密为密文然后提交给业务后端。但由于小程序本质上是基于H5技术,其安全性并不高。比如用在H5上,比较容易看出加密逻辑,或者加密强度不够强。第三方输入法监控、内存遍历等仍可能导致密码泄露等问题。 。
为了提高微信开放平台的生态安全,解决小程序内数字密码输入场景可能存在的安全问题,微信在组件中开放了安全键盘类型。通过引入安全键盘,小程序可以对用户输入过程中的关键信息进行加密,防止键盘窃听,并保护内存,有效保障用户数据资产的安全。
安全键盘保护原理
安全键盘采用非对称加解密算法,需要两个密钥,一个称为公钥,可以公开,另一个称为私钥,需要私密保存。公钥加密的密文只能用私钥解密,而私钥无法通过公钥计算出来,所以即使黑客获得了公钥,也无法解密密文。我们一般把公钥放在客户端(比如小程序环境)进行加密,私钥放在业务后端,这样只有后端才能解密。黑客攻击本地客户端比较容易,但侵入后端则困难得多。有些企业甚至将私钥存储在硬件加密机芯片中。在这种情况下,黑客无法获取私钥,因此使用非对称加解密算法是安全键盘推荐的方式,安全性可以得到保证。为了保证私钥的隐私价值,我们要求不同的小程序业务使用自己唯一的公私钥对,这样才能完美实现业务加密数据隔离。企业A的公钥加密数据只有企业A自己的私钥才能解锁。企业A的责任是保护自己独特的私钥。为了证明某个公钥属于A业务,我们会给A业务的开发者颁发一个数字证书,该数字证书由腾讯官方签名,保证可靠性和不可篡改。数字证书将绑定企业唯一证书。一些公钥和业务私钥是在向腾讯申请数字证书的过程中生成的。企业负责管理自己的私钥。在此过程中,腾讯只能获取企业的公钥,无法获取企业自己的私钥。密钥意味着即使是腾讯也无法解密小程序业务用户输入的密码。为了符合国家合规要求,我们为国产密码算法颁发数字证书,这意味着非对称加解密算法使用SM2算法,而不是RSA等国际算法。
不同的小程序业务对加密数据的格式可能有不同的要求。例如,当用户输入的密码为“”时,有的商家可以直接对明文进行加密,而有的商家可能会想先做哈希,然后再加密。例如,使用md5(“”),经过哈希处理后,可以更有效地保护用户的明文密码,使业务很难猜测用户的实际密码是什么。其他业务可能会使用sha1哈希算法sha1(""),也有业务使用国内比较合规的密码哈希算法sm3(""),有的业务甚至想添加一些易混淆的字符(密码学中称为salt)为了更好地保护密码的明文,有可能会变成 sm3("+abc"),其中“+abc”是额外易混淆字符的示例。因此,为了让不同的小程序业务能够拥有符合自身业务需求的加密格式,小程序安全键盘还开放了配置密码格式的能力,以便更好地与自己的整体业务融合,但这种格式不能普遍兼容,所以当您使用小程序安全键盘时,可能会涉及到修改一些后台验证服务的工作量。请提前评估可行性。
使用流程1生成证书签名请求
开发者可以自行生成公私钥和证书签名请求,也可以通过微信提供的工具生成证书签名请求。通过微信(/Mac)提供的工具生成证书签名请求的步骤如下:
通过SM2密钥对功能生成公钥和私钥
通过SM Cert CSR功能生成CSR

2 生成证书
在小程序管理后台“开发”-“开发管理”-“开发设置”-“安全键盘证书”部分填写CSR即可生成。
3 使用证书将生成的证书放入小程序代码包中。在组件中设置 type="safe-" 并设置相关参数(safe--cert-path、safe--time-、safe--、safe--、safe--salt、safe--hash)。代码示例
<input style="border: 1px solid blue;" type="safe-password" placeholder="123456" safe-password-cert-path="/minipro_test_cert.crt" safe-password-time-stamp="1618390369" safe-password-nonce="1618390369" safe-password-salt="zefengwang" safe-password-custom-hash="md5(sha1('foo' + sha256(sm3(password + 'bar'))))" bind:blur="onBlur" bind:input="onInput" value="{{value}}" >input> <button bind:tap="onClear">clearbutton> <view>{{detail}}view>
Page({ data: { value: '123' }, onInput(res) { console.log('onInput', res) this.setData({ value: res.detail.value, }) }, onClear() { this.setData({ value: '', }) }, onConfirm() { console.log('confirm') }, onBlur(res) { console.log('onBlur', res) this.setData({ detail: JSON.stringify(res.detail, null, 2) }) }, })
密文格式
为了保护用户密码,安全键盘使用各种加密算法来保护用户敏感信息。这些算法可以根据小程序业务的实际需求灵活配置,因为不同的小程序使用不同的密码加密格式,所以需要配置适合自己业务的配置。
小程序安全键盘加密的用户密码的一般格式如下:
'V02_' + sm2(header + timestamp + '\0' + pbkdf_hmac_hex(password, salt) + '\0' + nonce + '\0' + 随机数)

其中,()是计算安全键盘hash的算法表达式,可以通过safe---hash属性来设置。前两个字节用于标识密码哈希算法:
0x00 0x00:哈希值 0x00 0x07:
这种格式考虑了几个安全因素:
防重放:传入正确的时间戳,每次加密都会不断递增,保证即使密码相同,每次密文也会不同。防暴力破解:sm2非对称算法本身就保证了防暴力破解、防溯源的可能性。原文:内置算法,也可以自定义哈希算法;防彩虹表攻击:小程序开发者可自定义动态盐;
小程序开发者如果打算使用安全键盘,必须先在本地生成sm2密钥对,然后到小程序管理后台申请小程序安全键盘数字证书。证书颁发后需要与小程序代码一起发布。小程序调用安全键盘时,需要传入小程序安全键盘数字证书。完成证书有效性验证后,提取证书公钥并使用sm2算法对用户数据进行加密。由于采用证书公钥加密,只有开发者持有的私钥才能解密数据的明文。在网络传输过程中,即使密文被恶意截获,攻击者也无法获取明文。
如何解密或验证加密
'V02_' + sm2(header + timestamp + '\0' + hash(password, salt) + '\0' + nonce + '\0' + 随机数)
后台收到密文后,按照上述格式进行解析: 1、去掉密文的4字节前缀; 2、使用小程序安全键盘证书对应的sm2私钥解密获取明文数据; 3、解析明文数据,可以获取时间戳、密码哈希等字段;
首先,小程序开发者后台只能获取脱敏后的密码哈希,无法获取明文。当然,根据合规要求,后端不应该获取用户密码的明文。其次,小程序开发者应在后台妥善保存密码哈希,作为匹配用户密码是否一致的依据。例如,在用户注册或密码修改过程中,后台SM2私钥解密密码哈希后,应将密码哈希持久化在数据库(或其他存储技术)中。在后续用户登录或者其他需要密码验证的场景中,通过将用户请求的密码哈希与之前保存的密码哈希进行比较来判断密码是否已经验证。