【总结】公钥加密私钥解密/私钥加密公钥机密验证
来源:互联网 发布:免费.tk域名的注册 编辑:程序博客网 时间:2024/05/18 01:04
看到一篇文章:http://blog.csdn.net/cleble/article/details/50378829
联想到比特币以及工作内容所想到的问题。
RSA是非对称加密,用某篇文章的讲解就是说:假设有个黑科技的魔法机器,左边进的数据会唯一转换成右边的数据。右边不能进。
有了这个魔法工具,有左边的数据可以很容易的看到右边的数据。但是通过右边的数据完全不知道左边的数据。如果想知道,只能一个一个的去试,总有一天可以通过魔法工具试出右边数据的左边数据是什么。(看得懂吗?)
此处反思。。。
现在的问题是,有个反黑科技的魔法机器,专门怼上面的魔法机器。并且唯一职责就是只能从右边的数据获取左边的数据。右边的数据永远不知道左边的数据是什么。(看得懂吗?)
此处反思。。。
上面两种魔法机器每次运作都需要消耗一样东西。要么私钥要么公钥,并且两个成对使用。也就是说黑科技魔法工具使用私钥,那么反黑科技魔法工具就使用公钥。反之亦然。
现在的问题是,假设默认情况下是这样的:
黑科技魔法工具只能用私钥加密,反黑科技工具只能用公钥解密。如果某一天,有人一不小心给了黑科技魔法工具公钥,然后想投机取巧,给反黑科技魔法工具喂私钥。还能够解出数据吗?
先看代码:
首先是私钥加密公钥解密
1.16自己写的进制工具
package utils;import java.io.UnsupportedEncodingException;/** * * @author qq1623299667 * */public class HexUtil {/** * 将任何字符串按指定编码输出成特定格式的16进制 * @param string * @param charsetName * @return */public static String stringToHexString(String string,String charsetName) {StringBuilder sb = new StringBuilder();try {for (int i = 0; i < string.length(); i++) {char ch = string.charAt(i);byte[] bytes = String.valueOf(ch).getBytes(charsetName);String hex = bytesToHexString(bytes);sb.append(hex);}} catch (UnsupportedEncodingException e) {e.printStackTrace();}return sb.toString();}/** * 将字节码数组按16进制的方式保存为字符串 * @param bytes * @return */public static String bytesToHexString(byte[] bytes){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { int num = bytes[i] & 0xFF; String hex = Integer.toHexString(num); if (hex.length() < 2) { sb.append(0); } sb.append(hex); } return sb.toString();}/** * 将16进制的字符串转换成byte * @param hexString * @return */public static byte[] hexStringTobytes(String hexString){StringBuilder sb = new StringBuilder();for(int i=0;i<hexString.length()/2;i++){sb.append(hexString.substring(2*i,2*i+2));}hexString = sb.toString();byte[] bytes = new byte[hexString.length()/2];for(int i=0;i<hexString.length()/2;i++){bytes[i] = (byte)(0xff & Integer.parseInt(hexString.substring(2*i, 2*i+2), 16));}return bytes;}/** * 将16进制的字符串转换成string * @param hexString * @return */public static String hexStringToString(String hexString,String charsetName){try {return new String(hexStringTobytes(hexString),charsetName);} catch (UnsupportedEncodingException e) {e.printStackTrace();}return null;}/** * 将16进制字符串按特定格式格式化 * @param hexString * @return */public static String hexStringFormat(String hexString){StringBuilder sb = new StringBuilder();sb.append("\r\n");for(int i=0;i<hexString.length()/2;i++){sb.append(hexString.substring(2*i, 2*i+2).toUpperCase());sb.append(" ");if(i%16==15){sb.append("\r\n");}}return sb.toString();}}
2.加解密类
package privatekeyencryprsa;import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; public class EncrypRSA { /** * 加密 * @param RSAPrivateKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte[] encrypt(RSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if(privateKey!=null){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; } /** * 解密 * @param RSAPublicKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte[] decrypt(RSAPublicKey publicKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if(publicKey!=null){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; } }
3.测试类
package privatekeyencryprsa;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import javax.crypto.BadPaddingException;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import utils.HexUtil;public class TestRSA {/** * @param args * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws NoSuchPaddingException * @throws InvalidKeyException */ public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { EncrypRSA rsa = new EncrypRSA(); String msg = "可怜的测试工具"; //KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); //初始化密钥对生成器,密钥大小为1024位 keyPairGen.initialize(1024); //生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); //得到私钥 RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); //得到公钥 RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); //用私钥加密 byte[] srcBytes = msg.getBytes(); byte[] resultBytes = rsa.encrypt(privateKey, srcBytes); //用公钥解密 byte[] decBytes = rsa.decrypt(publicKey, resultBytes); System.out.println("明文是:" + msg); System.out.println("加密后是:" + new String(resultBytes)); System.out.println("加密后16进制是:" + HexUtil.hexStringFormat(HexUtil.bytesToHexString(resultBytes))); System.out.println("解密后是:" + new String(decBytes)); } }
4.测试结果
明文是:可怜的测试工具加密后是:?�k�����/��K�A�������jBk:����m���L0�N/�e'�}_��=���.&�*��r*_5����@��=���d����>�G��^���!��6*le�Y�w�2�Dr&�Oz�O�Y8�:��1加密后16进制是:3F 94 6B 95 8F F2 EB F1 2F F0 88 4B DF 41 CA 11 ED 28 08 AF FD FE 99 F2 6A 42 6B 3A C8 C4 D0 D6 6D 8A 83 96 4C 30 81 4E 2F E6 65 27 AD 7D 5F B1 8A 3D AF 89 B4 2E 26 F9 0B 2A BC A4 72 2A 5F 35 EF 89 F6 A4 E9 40 E5 17 C5 3D B4 81 17 EB 64 CA D1 01 A1 B6 3E F2 47 B8 C1 5E AB AC F7 21 D7 EE BD 36 2A 6C 65 F6 59 A5 77 EB 32 87 14 44 72 26 C3 4F 7A 14 9F 4F C5 59 38 81 3A B0 07 B8 15 31 解密后是:可怜的测试工具
然后是公钥加密私钥解密
1.加解密类
package publickeyencryprsa;import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; public class EncrypRSA { /** * 加密 * @param publicKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte[] encrypt(RSAPublicKey publicKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if(publicKey!=null){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; } /** * 解密 * @param privateKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte[] decrypt(RSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if(privateKey!=null){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; } }
2.测试类
package publickeyencryprsa;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import javax.crypto.BadPaddingException;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import utils.HexUtil;public class TestRSA {/** * @param args * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws NoSuchPaddingException * @throws InvalidKeyException */ public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { EncrypRSA rsa = new EncrypRSA(); String msg = "可怜的测试工具"; //KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); //初始化密钥对生成器,密钥大小为1024位 keyPairGen.initialize(1024); //生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); //得到私钥 RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); //得到公钥 RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); //用公钥加密 byte[] srcBytes = msg.getBytes(); byte[] resultBytes = rsa.encrypt(publicKey, srcBytes); //用私钥解密 byte[] decBytes = rsa.decrypt(privateKey, resultBytes); System.out.println("明文是:" + msg); System.out.println("加密后是:" + new String(resultBytes)); System.out.println("加密后16进制是:" + HexUtil.hexStringFormat(HexUtil.bytesToHexString(resultBytes))); System.out.println("解密后是:" + new String(decBytes)); } }
3.测试结果
明文是:可怜的测试工具1�'jC1y��`=N�G|���P�98o���������s1bb �b�O������n�C�^\�����ǹ�加密后16进制是:7E 5B 75 D2 19 20 EC 2C 5E 7E 86 4B 47 63 29 56 7C 66 F1 78 C0 2E B2 D9 D2 93 73 81 F8 E4 91 95 9E E4 E9 73 0F 31 14 62 7F 62 0D 31 D5 27 6A 43 31 79 D8 DB 60 3D 4E F8 47 7C FC 01 9F FA 50 BD 39 38 0E 6F 88 E1 06 ED 1B F1 ED B5 7F ED 0C E7 16 62 ED 4F DB E9 17 0A 90 A2 BE 0E F3 6E 87 43 E6 5E 5C BB FE 81 A0 E1 B3 7F C7 B9 05 E0 00 E6 3C F2 0C D6 54 6F 48 D0 AD B8 06 BB 39 8D DE CF 解密后是:可怜的测试工具
可以看到,即使有个粗心的小伙子弄错了该给黑科技魔法工具喂什么钥,他还是可以通过反黑科技魔法工具机智的找到原来的数据。
但是,他会发现不同,就是加密后的数据发生了更改。
例子就到这里,我们已经知道不论是公钥加密还是私钥加密。我们都可以从密文得到相应的明文。
我们现在需要反思的一件事就是:什么时候用私钥加密什么时候用公钥加密?
以下是我的一点见解,可能理解有错,请各位看官抱着只讨论不打脸的态度审视:
那种秘钥加密取决于具体的业务场景:
公钥加密类:收费软件的数据签名
私钥加密类:服务器给手机的通讯加密,比特币持有者数据签名
- 【总结】公钥加密私钥解密/私钥加密公钥机密验证
- 公钥加密,私钥解密(数据加密)----私钥加密,公钥解密(验证)
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
- 公钥加密_私钥解密
- 公钥加密-私钥解密(RSA)
- openssl公钥加密私钥解密 &私钥加密公钥解密
- RSA公钥加密私钥解密--jsp加密,java解密
- 公钥加密 私钥解密,私钥数字签名 公钥验证
- RSA公钥加密—私钥解密&私钥加密—公钥解密&私钥签名—公钥验证签名
- RSA加解密使用总结,.net私钥加密公钥解密,WinCE平台RSA加解密
- 问题以及私钥加密证书解密的总结
- 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#
- 用crypto api 实现公钥加密,私钥解密
- 公钥加密,私钥解密示例程序(JAVA)
- HDU 5245
- Spring之AOP的两种配置方式
- Apache Beam简介
- how 2 make screen shot for app
- 快用markdown写一篇博客吧
- 【总结】公钥加密私钥解密/私钥加密公钥机密验证
- python3[爬虫实战] 使用selenium,xpath爬取京东手机(上)
- usaco1.1你的飞碟在这儿
- 游戏开发流程
- poj 1273 Drainage Ditches【最大流 dinic】
- 函数返回值、引用和指针的区别思考
- 详解js中的setTimeout()函数
- 文章标题
- 概率性算法