Java中数据传输加密与签名那些事( 三 )

< encodePartLen; i++) {byte[] tempSorceBytes = decodeListData.get(i);int tempSourceBytesLen = tempSorceBytes.length;System.arraycopy(tempSorceBytes,0,decodeResultBytes,curPosition,tempSourceBytesLen);curPosition += tempSourceBytesLen;}decodeStrResult = new String(decodeResultBytes,"UTF-8");}catch (Exception e){e.printStackTrace();}return decodeStrResult;}}//运行结果//加密后:bapvkf7RsocUqpr7JJ5yMDQSrMAKnWVuHG2buJDhV0DGMTlAKezcy7Qyc8f5DVVHralZ5I0nSZdQOVaIG7ndP/bvtNcQVJaaigRSaQTfmf7xiNNuWQf71nQJmiUlHdzijUWB0HbilWBeZ71FZT9djoV1X6EZDB3oH1DQwwOmvow=//解密后:Java资料社区经过以上加密之后,基本上能很大程度解决数据在传输当中数据被泄漏的几率,但是并没法保证绝对的安全,RSA加密中如果公钥被泄漏,攻击者照样有办法能够根据泄漏的公钥,重新模拟一份加密数据传输到服务端,而服务端并没法辨别中途是否被篡改过,那么签名技术就是用于验证、防止中途是否被篡改;
 
签名:通过使用两对RSA秘钥 (A[公钥、私钥],B[公钥、私钥]) ,通常客户端存储A公钥、B私钥,服务端则存储A私钥、B公钥,A用于加解密,B用于签名以及验签;
 
流程:客户端用A公钥加密过后,再通过B私钥将加密过后的数据进行签名,最后将加密数据与签名一起发送到服务端,服务端接收到数据之后,首先通过B公钥对该加密数据以及签名进行对比验签,如果验证不一致则代表中途被篡改过,否则正常;
 
RSA签名案例:
public class RSASignature {public static void main(String[] args) {/*创建两份公私钥,map1用于加解密、map2用于签名*/Map<String,String> map1=RSAUtils.createRSAKeys();Map<String,String> map2=RSAUtils.createRSAKeys();String str="Java资料社区";String enStr=RSAUtils.encode(str,map1.get("public"));//map1公钥加密System.out.println("加密后:"+enStr);String sign=sign(enStr,map2.get("private"));//map2私钥签名System.out.println("签名:"+sign);//enStr+="1"; //模拟中途被篡改,则验签falseboolean flag=doCheck(enStr,sign,map2.get("public"));//map2公钥验签System.out.println("验签结果:"+flag);}/*** 签名算法*/public static final String SIGN_ALGORITHMS = "SHA1WithRSA";/*** RSA签名*/public static String sign(String content, String privateKey) {try {PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));KeyFactory keyf = KeyFactory.getInstance("RSA");PrivateKey priKey = keyf.generatePrivate(priPKCS8);java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);signature.initSign(priKey);signature.update(content.getBytes());byte[] signed = signature.sign();return Base64.encode(signed);} catch (Exception e) {e.printStackTrace();}return null;}/*** RSA验签*/public static boolean doCheck(String content, String sign, String publicKey) {try {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] encodedKey = Base64.decode(publicKey);PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);signature.initVerify(pubKey);signature.update(content.getBytes());boolean bverify = signature.verify(Base64.decode(sign));return bverify;} catch (Exception e) {e.printStackTrace();}return false;}}//运行结果://加密后:Nv1kTCukFAziwsCYPZQDQ8WqII1v5DKlTaFlcgkXQACuO01rFuvPAu/PXlmVuHN0i2Xx5B4ZjsKIs2YJHUzIunuqkPchKZM29b52jv7TLPaeZUeQFmC5GKEpEHSTWfUK9T7YF20+kK6Ey0rWRgOBd3ZoVPjvCoNXAlhyEYkBx7Q=//签名:fAkREdyQsioXeDi/CLaBQDP+V0K6W8DGXTBYZsH5GS8O30+ZKCfyTwvGNIZ++XIekt0P6xo1T6L7BRdT/it5qNwcqudxoolgf8KkhkSRFCI6LjJ6TYxFfCnvtMv7dxXDkR30E0AR9jyqNCUVE6ljUDsSL7PvUFpqOBDTcd+l2uA=//验签结果:true总结
1.对称加密效率性能高,由于秘钥存在泄漏的可能,并不能保证加密数据不被破解,建议对普通数据进行使用,对于敏感数据(金额、身份证等等)避免使用;
2.非对称加密效率性能低,分为公私钥两把,即使公钥泄漏,也能保证数据不被破解,建议对敏感数据进行使用;
3.通过非对称加密+签名能够很大程度防止传输过程中信息被篡改,但是并不是绝对的安全;
 
关注微信公众号"Java资料社区",更多干货等你学习;




推荐阅读