java RSA算法(一)
来源:互联网 发布:饥荒联机内存优化mod 编辑:程序博客网 时间:2024/06/07 02:10
RSA加密是非对称加密,密钥对分公钥与私钥。公钥是用来给别人加密的。但是呢,java生成的publicKey的getEncode方法返回的是java格式的公钥,其它平台是认识不了的。
例如生成512的公钥:
305C300D06092A864886F70D0101010500034B003048024100925FC3FC103F6E2209E77D8FAF59B48DE06AE86471CDD5D5A4FCA6A06070C38578F49444A73222A9B3DAFC8C71C2BE14ECDA5EDA0667BA91182CCB3546BB85AF0203010001
这个明显不止64个bytes。我们今天就说一下这个。
先看段生成公钥的代码:
public static TKeyPair RSAinitKey(int Length) throws Exception { KeyPairGenerator keyPairGen; keyPairGen = KeyPairGenerator .getInstance("RSA"); keyPairGen.initialize(Length); KeyPair keyPair = keyPairGen.generateKeyPair(); X509EncodedKeySpec keySpec=new X509EncodedKeySpec(keyPair.getPublic().getEncoded()); // X509EncodedKeySpec priKeySpec=new X509EncodedKeySpec(keyPair.getPrivate().getEncoded()); KeyFactory keyFactory=KeyFactory.getInstance("RSA"); RSAPublicKey publickey=(RSAPublicKey) keyFactory.generatePublic(keySpec); //PrivateKey privatekey=keyFactory.generatePrivate(priKeySpec); return new TKeyPair(keyPair.getPrivate().getEncoded(),publickey.getEncoded()); }
private static void test3() { try { TKeyPair keypair = CertificateUtil.RSAinitKey(512); System.out.println("私钥:"+CertificateUtil.bytesToHexString(keypair.getPriKey())); System.out.println("公钥:"+CertificateUtil.bytesToHexString(keypair.getPubKey())); RSAPublicKey pubKey = (RSAPublicKey) CertificateUtil.getPublicKey(keypair.getPubKey()); System.out.println("公钥模数:"+CertificateUtil.bytesToHexString(pubKey.getModulus().toByteArray())); System.out.println("公钥指数:"+CertificateUtil.bytesToHexString(pubKey.getPublicExponent().toByteArray())); PrivateKey priKey = CertificateUtil.getPrivateKey(keypair.getPriKey()); byte[] enData = CertificateUtil.encrypt(pubKey, hello.getBytes()); byte[] out = CertificateUtil.decrypt(priKey, enData); System.out.println(new String(out)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
测试一下,看一下打印结果:
私钥:30820155020100300D06092A864886F70D01010105000482013F3082013B020100024100B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA83020301000102407B1E5AE9F7D23EE98C4BCC16F55114FF7AAE5E8505DAABD97E0F07501B6A6F8B6EDFDF873E4117781A4ED845F96322BDF46FB1D3284A75FFFAAA96D620B5E439022100E40B3627F7F82F230710DC1702ACFB6126B25E12275D005371D50CCF4FDEA1A5022100C60FFCD75CDABC0F8381B16D40ADE9D24207C7FF3D58C187212F966DCF68E307022100AF794511DA483A152CF1B7396990ABDA24C9A9833490E6984F064E5613B24F15022046BC8302AF88F74D5B1C40AFD23FCA986B38B836F243F6AA3A31F2B9B92FAE95022100899AAF38D5B62870B1C23B5A13B272F813543171919C1C2EEE25AE9A38E22B36公钥:305C300D06092A864886F70D0101010500034B003048024100B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA830203010001公钥模数:00B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA83公钥指数:010001
发现公钥模数的长度是65,我们再用公钥模数和指数生成公钥,代码如下:
public static RSAPublicKey getPublicKey(String big1,String big2) throws Exception{ BigInteger b1=new BigInteger(big1,16); BigInteger b2=new BigInteger(big2,16); RSAPublicKeySpec rsaPubKS=new RSAPublicKeySpec(new BigInteger(big1,16),new BigInteger(big2,16)); KeyFactory kf=KeyFactory.getInstance("RSA"); return (RSAPublicKey) kf.generatePublic(rsaPubKS); }
这里面参数,big1是模数,big2是指数。
static String big1="00B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA83"; static String big2="10001"; private static void test4() { try { RSAPublicKey pubkey = CertificateUtil.getPublicKey(big1, big2); System.out.println("公钥模数:"+CertificateUtil.bytesToHexString(pubkey.getModulus().toByteArray())); System.out.println("公钥指数:"+CertificateUtil.bytesToHexString(pubkey.getPublicExponent().toByteArray())); System.out.println("公钥:"+CertificateUtil.bytesToHexString(pubkey.getEncoded())); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
测试一下,打印结果:
公钥模数:00B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA83公钥指数:010001公钥:305C300D06092A864886F70D0101010500034B003048024100B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A
生成的公钥一样。刚刚说,公钥模数应该是64bytes,我们去掉最前面一个byte,big1为B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA83时,再跑一下,打赢结果:
公钥模数:00B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA83公钥指数:010001公钥:305C300D06092A864886F70D0101010500034B003048024100B06EE9C5F7923031F313AABA8E9E5F43D35CEF2CEC77C73203D7CB329451E65E467ADDC5DEA1524D7E36625A09A61E38368215615E5670EB43C925E4AE73BA830203010001
一样的,也就是说生成的是64个bytes,我们回头再看看第一段,如果我们设置length把512改成588,
私钥:3082017D020100300D06092A864886F70D01010105000482016730820163020100024A0A86CD8C18CDBF06986F83DD74A372296312E026C07B3ACA4D4B77FDF297901BBB624B51F3F117F445F22F4E41C964E410A8FD05E180ECDEE86F1AD448EC4346E93D52D562B88AF3EB490203010001024A05976D7FC97D20C7641978361E4AE3CD502F2A99EB0C8A4203A4DEEC29FC9033EAE95F90FC874C3737A50916386BF31B80CBE0FDB3DF69CCC646B3ACF2161AC135051336F2A0B89539B102253DC4CD4BB2951605608762B4122E07EADAD148D4D4359DB9CF6FD6397A36951DB16FD860DF02252BA095763B3E5C94FDF95D906C51E83FADAF3FB6919D8068522DC77680E528049C6C4770D702253DB8FAAC39B76059DF2B6A2626447904E5C35BD3D07A03323966B7DA9795134CA891EAD661022527A6012F3A182ABB9D350B3B3DB612840CACC01283B3C80706E863E5E6AE5BF814D0B2FC710225107F1D24BC2A8EB55E464601CCA160E13D979807E5EB03C2AFD4D3026520E0E800197FD096公钥:3065300D06092A864886F70D01010105000354003051024A0A86CD8C18CDBF06986F83DD74A372296312E026C07B3ACA4D4B77FDF297901BBB624B51F3F117F445F22F4E41C964E410A8FD05E180ECDEE86F1AD448EC4346E93D52D562B88AF3EB490203010001公钥模数:0A86CD8C18CDBF06986F83DD74A372296312E026C07B3ACA4D4B77FDF297901BBB624B51F3F117F445F22F4E41C964E410A8FD05E180ECDEE86F1AD448EC4346E93D52D562B88AF3EB49公钥指数:010001
公钥模数是74个bytes,588/8 = 73.5,再用模数月指数生成公钥:
公钥模数:0A86CD8C18CDBF06986F83DD74A372296312E026C07B3ACA4D4B77FDF297901BBB624B51F3F117F445F22F4E41C964E410A8FD05E180ECDEE86F1AD448EC4346E93D52D562B88AF3EB49公钥指数:010001公钥:3065300D06092A864886F70D01010105000354003051024A0A86CD8C18CDBF06986F83DD74A372296312E026C07B3ACA4D4B77FDF297901BBB624B51F3F117F445F22F4E41C964E410A8FD05E180ECDEE86F1AD448EC4346E93D52D562B88AF3EB490203010001
发现一样的噢,于是,我们发现如果我们把公钥指数与公钥模数都传给对方,不管任何一个平台,我想都能用公钥加密了吧!
demo下载http://download.csdn.net/detail/gongkanaa/9810310
包含pc端加解密验证工具(很强大)!
- java RSA算法(一)
- RSA算法(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- RSA算法原理(一)
- oracle 导入导出详解
- Python学习笔记(基础篇)_007_字符串的各种变态方法
- Python学习笔记(基础篇)_008_函数
- Android带编辑框的对话框
- Python学习笔记(基础篇)_009_嵌套函数
- java RSA算法(一)
- Android API中隐藏的类使用(例如IWindowManager)
- Python学习笔记(基础篇)_010_lambda表达式
- POJ1009
- 寓情于景 —— 情与景的交融
- JAVA_QUARTZ 定时任务
- Python学习笔记(基础篇)_011_字典
- Android 中对 aar 文件的使用攻略
- QHeaderView添加右键菜单