1.先约定一个秘钥,写死,比如aabbccdd(每个产品一个)
2.app用tcp申请通信秘钥,这个请求用aabbccdd加密.
3.云端用aabbccdd解密,知道是申请秘钥,然后返回一个秘钥bbccddeeff,这里这个秘钥是用aabbccdd加密的(安全问题),
4.设备用aabbccdd解密出秘钥bbccddeeff,然后后面的通信用bbccddeeff来加解密,
5.秘钥有有效期.
风险,如果别人知道aabbccdd初始秘钥,会激活成功教程通信内容的.这个只是tcp接口,所有后面我们直接统一用https接口了.这种方案不要了.
但是有的设备用其他平台,比如电信,移动的OneNet平台,需要传输数据,对于他们,需要透传一些数据,所以还是需要用到秘钥的,这里又提供另外的解决方案;
使用ECDHE密钥交换算法交换公钥,这里可以参考
https://blog.csdn.net/mrpre/article/details/
大概流程如下,

上面这个流程,可以简化一下:
1 设备烧固件的时候直接存了服务器的公钥a,少一步交互,都是存在加密芯片(安全),现在的设备基本都需要加密芯片了
2,设备另外上报一个公钥c,服务器接收到这个设备,算出共享秘钥,pubKey=前缀+c,priKey=b,这样子保证每个设备的加密因子都是不一样的,都是根据设备上报上报的公钥c计算的,这里获取到的加密因子,可以截取部分,这样子又增加激活成功教程难度.
3.采用下面这个算法,一起算出私钥,然后这个设备以后的数据都统一用这个私钥来加密来通信,除非重新上报一个公钥,加密因子才会修改.
4.因为设备有加密芯片.你输入加密字符串,直接输出解密的数据了.
5.即使服务器公钥私钥都被拿到(开发人员),但是每个设备上报的公钥不一样,也是激活成功教程单个设备,设备有加密芯片,其他设备也是安全的.
代码如下:
/ * 加密因子 * @param pubKey * @param priKey * @return * @throws Exception */ public static String getECHDSecret(String pubKey,String priKey) throws Exception { try { byte[] pubKeyBytes = ECCCoder.hexToBytes(pubKey); X509Key x509key = new X509Key(); x509key.decode(pubKeyBytes); ECPublicKey alicePub = (ECPublicKey) ECKeyFactory.toECKey(x509key); byte[] privKeyBytes = ECCCoder.hexToBytes(priKey); PKCS8Key pkcs8Key = new PKCS8Key(); pkcs8Key.decode(privKeyBytes); ECPrivateKey alicePvt = (ECPrivateKey) ECKeyFactory.toECKey(pkcs8Key); byte[] alicePubEncoded = alicePub.getEncoded(); KeyFactory aliceKf = KeyFactory.getInstance("EC"); PublicKey remoteBobPub = aliceKf.generatePublic(new X509EncodedKeySpec(alicePubEncoded)); KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("ECDH"); aliceKeyAgree.init(alicePvt); aliceKeyAgree.doPhase(remoteBobPub, true); String secret=toHex(aliceKeyAgree.generateSecret()); return secret; } catch (Exception e) { e.printStackTrace(); } return null; }
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/126755.html