APP与服务器之间数据传输加密可采用对称加密(DES)和非对称加密(RSA)两种方式,对称加密是APP和服务器用一个密钥,而非对称加密算法需要两个密钥:公钥(publickey)和私钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。APP和服务器各自保存一个密钥。
我们用MD5进行签名,AES和RSA进行数据加密,确保数据安全。以下为一个简单的例子。
加密
将原始数据进行MD5字典排序然后加密得到签名,拼接在原始数据上,再用随机生成的aeskey进行加密。并将aeskey通过公钥加密拼接在请求数据上作为最终请求数据。
生成秘钥和MD5key
首先随机生成一个MD5key,双方都存储起来用于进行验签 。
String md5Key = "27d9c492c14a4f77ba0cc5022fc2bcd5";
然后生成公钥和私钥,用于加密解密。(此处例子加密时用公钥,解密时候用私钥。)
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0+DT38n56iiy2BOKdwfdnlEAVqGqc9K3BMvSe4AM8oXhQUX5UCsLU83Cm574bc0LbEyQ7ErfWBI8ihh+bcwCPppDFpX6XsfrKdzUUym/sK5RVldEBwnBvidMlgJCJy5/+VCAQftdILLKLq8fH04+3q8VI+1k5dHOJ5Wylu0+wPQIDAQAB";
String privateKey="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCfIe/PMwnWJOGJDIL/GXzarYRvj/0Um4Ef3kLVH6ieAdraqJk4elWh3FHU9Nj+5R3Gnty2NZ61ZPyykKHoHG8/rKntcEPc1GkK94tHrfdmkaOt+ZqSiMwaJ7TmEfNjxUPT+8WfANvK+wSg6yGspgpiCzwdnDeLLRaQ6cqZeUjH6uSONyS3V064GuHXteX3F37s1ifYIDwK8qbW6oYve1WTA7YCFH3ERugxmEubWjqz3vs6rUpvCankUxtSoiUl6UyestZ68bWgFfQmkOlY9rq4NfMes4d+5b0PomsplLe+Ir6I1HO+7rBlpHytk5Ro1H11U4ExIrbosLiuacHx9bdbAgMBAAECggEAMBY1PUuTAV8LuDpLq4KsM/iTOJMuSvfiwRqM35I9heHRnJmuE18EWXEWWV/T4tKheM+wqm7xkqb9pYgHJPjStU8b2mA+YZDeXS4IrJRpWllQONZgWz9zTcQJ6iwqfE+z+27tfOrpgCDyeR4UgvN5177FX71BG5F4bDn5uv7ne2GIbr19AkWQe376MLpCyVn2+1sSuWs3aexPo6DrE8/XPBSDz8yZGItPzKVmr0Ht+qsNiwWeRQJIpcWmbzlL+0NliYiE2jEn6mWqYOTWSiOp9TEaWjFW84BEwcatlt6YpmqUNh56MTS2QODLpkaF/3PjXlL3Sv4gCppVdC+H8fi54QKBgQDqVwwET8AtigM/olUucIaL27/peIpwCFUOBdoqRl4D+qZcs1khtPWtEquXGQtHE0o0az0dZ8DPWdvKAlBu7Ad9iBCDAl4WOhLPxda2U1c9IB4m1NDQPLMSyquEaFJ8XfizoOIFZFPSj3LkvQqL9Oz1iegZGregqozUsGOaQ9EuBwKBgQCt11TA9QbVDdWVFC0er4Ia957grKef/jlefgQEkYmNoLFSbS6M9apeb+HAfxg63xTMutFrZ44rxXxHX/AmyM64A+PBhQMTOjI8pZxgBSHkyig/I2t3IaH8giQMsAm5AoiHTavLsEwSjpeao+32BQVUSaaXAw/JCQG2MwK9nD5XDQKBgFLOS4rCe5Ab8qXrwNnWHVUSY7AmThTkfNmlq7/AebxCN8MOBPLqNN3heQy9ZsTIxjHbqw7W+MTMZePuCWoIsWTkTaFdls2X28nbiNGIhY0t6jmifd73c/ex8gWpr2wO8LDYqsVo/E2tLtYxDqcB9zGUd5VXYYe+fGEzqx551FLFAoGAUIACU0gj3c0GNn6dVjRXvz0jaU8KYGBNGKCqI6NxWxAqjMzaXZP1TL3qgEVaZwiejR+FkoLlpwdQQYz/nDYo47WJZje98M1mLgdSnnRB+bxTXsl8HjKI3HE3WFi8Z9vwdRdWkoAU+hLlyUpYCzDQAvQIHK3iRWnSTRjaEAumIpECgYEAk6cs0z5QH9yYW3i8v25j6u0XI0Epa9EUd0wrsvNjHEF+AR1DOQx7Vy0GvkgITbTC2si0FzDFjzqDpW1/JyQIU7jOJopV2mqNgUhpibpo1+8AtuERIQ5jnHx2ct0r98tdjVnC3ZZ3pYjeDep7PfkZCeqKj5ZNZCFTrCpQ70kGcnE=";
数据加密
原始请求json数据如下
{"data":{name":"zhangsan","address":"beijing"}}
首先根据key值字典顺序进行排序,排序后得到数据如下
{"data":"CfwzyAyRKIFpn+Mnzt/7DbKsdpQfRC6l3LNVXfY9uh+bA2tSqGzlL5CFu06lqn+8aD7yFFDhnMNbQnLVEoML0x4bG8/EomQrTpE9yYlHk9fjFHtzJ2cC/DkxGY4sbtmW","token":"plQ7WyJfppvoOMVeBtE7wJRAnJptqE9B7HzFseq/EeKEJtSsIz8eugglqYeWjF0nUtkO5IopHh6PzzgYJDjOuW44cyIMSNNMZTwZwA0PIQ3Kr9hQ7ld07sBKmSzRx9PiZS/EJr0ZRD1uae3Kyefbr4v1B8oXyh2nyY2ln0i7J3A="}
然后根据md5key进行加密作为签名拼接在原始请求数据串内用户解密时候进行验签
{"data":"CfwzyAyRKIFpn+Mnzt/7DbKsdpQfRC6l3LNVXfY9uh+bA2tSqGzlL5CFu06lqn+8aD7yFFDhnMNbQnLVEoML0x4bG8/EomQrTpE9yYlHk9fjFHtzJ2cC/DkxGY4sbtmW","token":"plQ7WyJfppvoOMVeBtE7wJRAnJptqE9B7HzFseq/EeKEJtSsIz8eugglqYeWjF0nUtkO5IopHh6PzzgYJDjOuW44cyIMSNNMZTwZwA0PIQ3Kr9hQ7ld07sBKmSzRx9PiZS/EJr0ZRD1uae3Kyefbr4v1B8oXyh2nyY2ln0i7J3A=","sign":"0c507b13f3bab53560ff1f676ba9a257"}
随机生成一个16位的字符串当做AESKey,将上述带有签名的数据进行Aes加密
aesKey:a9a9ce4af4df42e9
讲上述拼接了签名后的请求数据value值进行aes加密 得到结果
{"data":DMk7Eb12BeI2WOGbi6SNspfDqaCkRUH5VFJeJLlC4Ys6bPvmQ59Qg7i+nfXreweYzbEO0vyb1EJwf4wFoJAhNTK8a9WtG7UsXda4lEV1bAxlbsnHd8Vplgt7BXgHUyV/}
因为解密时候要用到aeskey解密,所以要将aeskey拼接到请求数据中,但为了数据安全 没有直接拼接,而是用rsa来进行公钥或者私钥加密(此处用的是公钥),解密时候用私钥解密便能得到aeskey,以下为上述请求数据再拼接了key为token,value值为rsa加密后的aeskey的数据作为最终请求数据。
{"data":"DMk7Eb12BeI2WOGbi6SNspfDqaCkRUH5VFJeJLlC4Ys6bPvmQ59Qg7i+nfXreweYzbEO0vyb1EJwf4wFoJAhNTK8a9WtG7UsXda4lEV1bAxlbsnHd8Vplgt7BXgHUyV/","token":"K4tvu+rb73k8PuLg4Q20j0F5BbI1M0fBJ8SUHZp7at90kEO3EHIUiWUJ1NLoTcv1MEqzFC6sgqwf6P53iGMWO9WzYq7x0JsANtJiZy76b5TlNx4oKBmdV9TCQN2I2Ga8Q7Q56lfGriIOP5vY3cDsGpIYG/y7eOdTo5WxZldjG/w="}
流程如下
String param="{\"data\":{name\":\"zhangsan\",\"address\":\"beijing\"}}";
JSONObject paramsJson = JSONObject.parseObject(params);
JSONObject dataJson = paramsJson.getJSONObject("data");
String md5Str = SecretUtils.getMd5Str(dataJson.toJSONString());
String sign = SecretUtils.getMD5(md5Str , md5Key);
dataJson.put("sign", sign);
String aesKey= UniqueIdUtils.uuidHex().substring(0, 16);
String token = SecretUtils.encryptForRsa(aesKey, publickey);
paramsJson.put("token",token);
String secretDataStr= SecretUtils.encryptForAes(dataJson.toJSONString(),aesKey);
paramsJson.put("data", secretDataStr);
解密
首先取到key为token的value值,然后用私钥进行rsa解密得到aeskey,然后用aeskey将data中的数据进行解密得到拼接了签名的原始数据,最终在将原始数据进行签名与签名比对,若是比对成功则延签成功,否则失败。
流程如下
String response="{\"data\":\"ewYp2LjLmsV0CSCDvho2RJzZNdRAKY3OTU/HYMOe7Zv/GBxqsoM8v2koY2OEgErTQ5GHR8oB4jJJ3/smi+C95QbiOwAjUpFpILWfIlQ4FgcJarE8qc9ZrM4z1Pg+7wNz\",\"token\":\"InXuTPmT6J8J+YruXTb9py2QfVGb97E21GtuU5SjPT+JpXJFv2bKGoDyZdt9/igvfxXHRdFRmYd5oWCv68sPsl7+/yXmmJionpE725OebcgxWgVApsEXRs3x/pp08vqdUfaRZaGoew0xLuir1WDRIPev3ag2bxuft2gzlXPVFmk=\"}";
JSONObject responseJson = JSONObject.parseObject(response);
String token=responseJson.getString("token");
String aesKey = SecretUtils.decryptForRsa(token, publickey);
String secretDataStr=responseJson.getString("data");
String decryptForAes = SecretUtils.decryptForAes(secretDataStr, aesKey);
JSONObject dataJson = JSONObject.parseObject(decryptForAes);
String md5Sign = dataJson.remove("sign").toString();
String md5String = SecretUtils.getMd5Str(dataJson.toJSONString());
boolean flag = SecretUtils.signMd5(md5Key, md5String, md5Sign);
if (!flag) {
return "md5验签失败";
}
responseJson.put("data", dataJson);
以上为一个简单的流程示例,作为一个简单的总结也希望对大家有帮助。
转载请标明源地址 https://blog.youkuaiyun.com/weixin_39620735/article/details/103627926
本文介绍了一种APP与服务器间数据加密传输的方法,使用MD5进行签名,AES和RSA进行数据加密,确保数据安全。详细解释了加密和解密流程,包括生成秘钥、数据排序、签名、随机AESKey生成及数据加密。
161

被折叠的 条评论
为什么被折叠?



