Java非对称加密算法--RSA
2015-11-23 14:18
411 查看
非对称加密的特点是有两把钥匙,公钥和私钥。公钥加密只能私钥解密;私钥加密只能公钥解密。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
这种加密算法的特点主要是密钥的变化。DES只有一个密钥,相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验,确保数据在传输过程中不被修改。
Java示例
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
这种加密算法的特点主要是密钥的变化。DES只有一个密钥,相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验,确保数据在传输过程中不被修改。
Java示例
package com.zzj.encryption; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; public class RSATest { static final String ALGORITHM_RSA = "RSA"; static final String ALGORITHM_SIGN = "MD5withRSA"; static String publicKey = null; static String privateKey = null; public static void main(String[] args) throws Exception { // 生成公钥和私钥 generatorKeyPair(); String source = "我是程序猿!"; System.out.println("加密前的数据:\r\n" + source); System.out.println("--------------------------公钥加密,私钥解密------------------------------"); // 公钥加密 String target = encryptionByPublicKey(source); // 私钥解密 decryptionByPrivateKey(target); System.out.println("--------------------------私钥加密并且签名,公钥验证签名并且解密------------------------------"); // 私钥加密 target = encryptionByPrivateKey(source); // 签名 String sign = signByPrivateKey(target); // 验证签名 verifyByPublicKey(target, sign); // 公钥解密 decryptionByPublicKey(target); } /** * 生成密钥对 * @throws Exception */ static void generatorKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); byte[] keyBs = rsaPublicKey.getEncoded(); publicKey = encodeBase64(keyBs); System.out.println("生成的公钥:\r\n" + publicKey); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); keyBs = rsaPrivateKey.getEncoded(); privateKey = encodeBase64(keyBs); System.out.println("生成的私钥:\r\n" + privateKey); } /** * 获取公钥 * @return * @throws Exception */ static PublicKey getPublicKey() throws Exception { X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(decodeBase64(publicKey)); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA); return keyFactory.generatePublic(publicKeySpec); } /** * 获取私钥 * @return * @throws Exception */ static PrivateKey getPrivateKey() throws Exception { PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(decodeBase64(privateKey)); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA); return keyFactory.generatePrivate(privateKeySpec); } /** * 公钥加密 * @param data * @return * @throws Exception */ static String encryptionByPublicKey(String source) throws Exception{ PublicKey publicKey = getPublicKey(); Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); cipher.update(source.getBytes("UTF-8")); String target = encodeBase64(cipher.doFinal()); System.out.println("公钥加密后的数据:\r\n" + target); return target; } /** * 公钥解密 * @param target * @throws Exception */ static void decryptionByPublicKey(String target) throws Exception{ PublicKey publicKey = getPublicKey(); Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); cipher.update(decodeBase64(target)); String source = new String(cipher.doFinal(), "UTF-8"); System.out.println("公钥解密后的数据:\r\n" + source); } /** * 公钥验证签名 * @return * @throws Exception */ static void verifyByPublicKey(String target, String sign) throws Exception{ PublicKey publicKey = getPublicKey(); Signature signature = Signature.getInstance(ALGORITHM_SIGN); signature.initVerify(publicKey); signature.update(target.getBytes("UTF-8")); if (signature.verify(decodeBase64(sign))) { System.out.println("签名正确!"); } else { System.out.println("签名错误!"); } } /** * 私钥加密 * @param data * @return * @throws Exception */ static String encryptionByPrivateKey(String source) throws Exception { PrivateKey privateKey = getPrivateKey(); Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); cipher.update(source.getBytes("UTF-8")); String target = encodeBase64(cipher.doFinal()); System.out.println("私钥加密后的数据:\r\n" + target); return target; } /** * 私钥解密 * @param target * @throws Exception */ static void decryptionByPrivateKey(String target) throws Exception { PrivateKey privateKey = getPrivateKey(); Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); cipher.update(decodeBase64(target)); String source = new String(cipher.doFinal(), "UTF-8"); System.out.println("私钥解密后的数据:\r\n" + source); } /** * 私钥签名 * @param target * @return * @throws Exception */ static String signByPrivateKey(String target) throws Exception{ PrivateKey privateKey = getPrivateKey(); Signature signature = Signature.getInstance(ALGORITHM_SIGN); signature.initSign(privateKey); signature.update(target.getBytes("UTF-8")); String sign = encodeBase64(signature.sign()); System.out.println("生成的签名:\r\n" + sign); return sign; } /** * base64编码 * @param source * @return * @throws Exception */ static String encodeBase64(byte[] source) throws Exception{ return new String(Base64.encodeBase64(source), "UTF-8"); } /** * Base64解码 * @param target * @return * @throws Exception */ static byte[] decodeBase64(String target) throws Exception{ return Base64.decodeBase64(target.getBytes("UTF-8")); } }结果:
生成的公钥: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcQiaArjqiJeDPT8RCmkwrKi1Bh4Y16wH49u1jmX3RQdf0B2tRD42bItY1oqZtqj/2xqDdXLSOWOr3aldwr6ucofMPEUm2l4sJnTrM96IVNOl8jIqw2d8m7P/PhyOfTgvtOemm725y4TJm3F0q0c1WfjO55orNUTolAmoOW57SQQIDAQAB 生成的私钥: MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJxCJoCuOqIl4M9PxEKaTCsqLUGHhjXrAfj27WOZfdFB1/QHa1EPjZsi1jWipm2qP/bGoN1ctI5Y6vdqV3Cvq5yh8w8RSbaXiwmdOsz3ohU06XyMirDZ3ybs/8+HI59OC+056abvbnLhMmbcXSrRzVZ+M7nmis1ROiUCag5bntJBAgMBAAECgYAz7pRHTiB0hWw62kLa89b+vYy+66DCSLGmIcLxyDCVnHF+S/zxut6QQbq5pq3zYpLRnGAYUdg8OvcUdYZMEEZTR4p5TMG7N758kyKMYcJaNKFY9q0xMNtsHK5r8qoLvrb5241w7i9JVgmz0wBjHLBR8AYbaetdA9AcKxPkD7i/ZQJBAPWTp6P3/WPVtaIADzBgKHOA+fZKrESweUpGeY5ay2SoSw/3KMPnros2WXV4Kgjhc4DxnslsbCw1x95xjlwprOsCQQCi4/7dzG3JbRaQD5OvmeMtPSUctOsc1RszA4QCO/h9r0V4es18ch81hXZo8urvOHbXsablbA7nfJnYLC2KdIKDAkAriMt1M+dFpYMXfu8yYjmJkFm/oak8XBSEaE3wQIRCCduUrvoZEJ9OqondWzoIbP8u4qaFiqT6iWYvNu5HxFOVAkBetD4fCFcgUBtZIKVV6Bur1qv4F7vGZKROsZGTlvhvYnL6jDNiUhuRC4p/lBRBh0uZNkF5i6zSq5/qjizgHcMvAkAtqC7qrt9wppcBtActXK23mrIBoCjCWP8zTLOYjuQsusfwaKl69gjUKv29Rd36LsrQW/5XvCSlYXonN1YJcqL5 加密前的数据: 我是程序猿! --------------------------公钥加密,私钥解密------------------------------ 公钥加密后的数据: TJZlueYjat5gFTWtGXzafN2TNAsG4D6HiSOjX9h/mm/WMtaUWOXVvySD5iHBhQmEL+Hqa6TG8sSm6aVESQFqhKgHuni4GhD/ctC5vCD6aL0K9oLlpo4oV5RZJIQfIfYB28ZJW59fE6E4GYMxyQca/hulK/jaZJFmU5esxvkZaSg= 私钥解密后的数据: 我是程序猿! --------------------------私钥加密并且签名,公钥验证签名并且解密------------------------------ 私钥加密后的数据: iAu34RZPt0LH4+5EyATXYDIJ5dCcTHpapXjsO2riRiEBdh1lhMNmOmTbAGhBUC7FyneHhQY3nwOWwS99w7e06y95YegRrotvoN3ss6xo8G3/cX1eTdzaXTadOkJR++Npj8SsodAZ675gHcUkTENkRmcBA4wuozUCzCJc7Pg3AMk= 生成的签名: SzUGGICDv1JOen09qeYSH+UHB2B2XBCI4zPkDo8JVkRr3YVKSj465nmQWNxoXqAZFcUyxjlWVAbEfE+KnrGP56lv01vwL84J2j5v5hhmwShclgbMDUi6OQt+4ACXBn1Er8zF/DJfK6USP2jJPaUL4U1vZUzEOE2AXOChcpYMHDw= 签名正确! 公钥解密后的数据: 我是程序猿!需要注意的是,不能公钥签名私钥验证,那样的话谁都可以对数据签名,无法防止伪造数据。
相关文章推荐
- PDF模板报表导出(Java+Acrobat+itext)
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Java - 反射机制(Reflection)
- Java操作ini文件
- Java - 常用类
- Java 通用的DES加密工具类的实现
- java基本知识(二)
- spring框架学习(六)AOP
- spring框架学习(五)注解
- Java - 多线程
- spring框架学习(四)自动装配
- Eclipse安装SVN插件教程
- spring框架学习(三)junit单元测试
- spring框架学习(二)依赖注入
- Java的文件读写操作
- spring框架学习(一)
- JAVA 3DES加密解密
- Java - 文件(IO流)
- Mac 环境下配置opencv(Eclipse)
- jar命令成功完成 java -jar 命令却提示“没有主清单属性”!