非对称加密------RSA
来源:互联网 发布:分销平台源码 java 编辑:程序博客网 时间:2024/05/17 12:24
概念
RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
源码
如下为RSA加解密的Java实现:
package cn.silence.encrypt;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;import java.security.*;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;/** * Created by Silence on 2017/12/15. */public class RSACoder { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "PublicKey"; private static final String PRIVATE_KEY = "PrivateKey"; /** * Base64解码密钥 * @param key 密钥 * @return byte[] 解码后密钥 */ public static byte[] decryptBASE64(String key) { return Base64.decodeBase64(key); } /** * Base64编码密钥 * @param bytes 密钥 * @return String 编码后密钥 */ public static String encryptBASE64(byte[] bytes) { return Base64.encodeBase64String(bytes); } /** * 初始化密钥 * * @return Map<String, Key> 初始化后密钥数据 * @throws Exception */ public static Map<String, Key> initKey() throws Exception { //密钥对生成器,参数为算法名称,KeyPairGenerator包含四中算法:DiffieHellman、DSA、RSA和EC KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化密钥大小,单位是位数bits keyPairGen.initialize(2048); KeyPair keyPair = keyPairGen.generateKeyPair(); Map<String, Key> keyMap = new HashMap<String, Key>(); //公钥 keyMap.put(PUBLIC_KEY, keyPair.getPublic()); //私钥 keyMap.put(PRIVATE_KEY, keyPair.getPrivate()); return keyMap; } /** * 获取私钥(BASE64编码后) * * @param keyMap 已初始化密钥数据 * @return String 私钥 * @throws Exception */ public static String getPrivateKey(Map<String, Key> keyMap) throws Exception { Key key = keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 获取公钥(BASE64编码后) * * @param keyMap 已初始化密钥数据 * @return String 公钥 * @throws Exception */ public static String getPublicKey(Map<String, Key> keyMap) throws Exception { Key key = keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 获取私钥对象 * * @param keyMap 已初始化密钥数据 * @return Key 私钥对象 * @throws Exception */ public static Key getPrivateKeyNoBase64(Map<String, Key> keyMap) throws Exception { return keyMap.get(PRIVATE_KEY); } /** * 获取公钥对象 * * @param keyMap 已初始化密钥数据 * @return Key 公钥对象 * @throws Exception */ public static Key getPublicKeyNoBase64(Map<String, Key> keyMap) throws Exception { return keyMap.get(PUBLIC_KEY); } /** * 用私钥对数据进行数字签名 * * @param data 原始数据 * @param privateKey 私钥 * @return String 签名后数据 * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { //解码由Base64编码的私钥 byte[] keyBytes = decryptBASE64(privateKey); /** * 大家肯定会对如下操作有些困惑,如下操作是还原私钥的过程,因为初始化生成私钥后对私钥进行了Base64编码并生成字符串, * 这里需要将编码后的私钥字符串还原成具体的私钥对象 */ //借助PKCS8EncodedKeySpec还原私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); //指定加密算法RSA KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //获取私钥对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); /** * 对原始数据生成数字签名 */ Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return encryptBASE64(signature.sign()); } /** * 验证签名后数据 * * @param data 原始数据 * @param publicKey 公钥 * @param sign 签名后数据 * @return boolean 验证结果(成功:true 失败:false) * @throws Exception */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { //解码由Base64编码的公钥 byte[] keyBytes = decryptBASE64(publicKey); /** * 如下操作即还原公钥的过程 */ //借助X509EncodedKeySpec还原公钥 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); //指定的加密算法RSA KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //获取公钥对象 PublicKey pubKey = keyFactory.generatePublic(keySpec); /** * 根据原始数据验证签名后数据 */ Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); return signature.verify(decryptBASE64(sign)); } /** * 用公钥加密数据 * * @param data 原始数据 * @param key 公钥 * @return byte[] 加密后数据 * @throws Exception */ public static byte[] encryptByPublicKey(String data, String key) throws Exception { //解码由Base64编码的公钥 byte[] keyBytes = decryptBASE64(key); /** * 如下操作即还原公钥的过程 */ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); //对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data.getBytes()); } /** * 用私钥解密数据 * * @param data 加密后数据 * @param key 私钥 * @return byte[] 解密后数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{ //解码由Base64编码的私钥 byte[] keyBytes = decryptBASE64(key); /** * 如下操作即还原私钥的过程 */ PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 用私钥加密数据 * * @param data 原始数据 * @param key 私钥 * @return byte[] 加密后数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { //解码由Base64编码的私钥 byte[] keyBytes = decryptBASE64(key); /** * 如下操作即还原私钥的过程 */ PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 用公钥解密数据 * * @param data 加密后数据 * @param key 公钥 * @return byte[] 解密后数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { //解码由Base64编码的公钥 byte[] keyBytes = decryptBASE64(key); /** * 如下操作即还原公钥的过程 */ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 用公钥对象加密 * * @param data 原始数据 * @param key 公钥对象 * @return byte[] 加密后数据 * @throws Exception */ public static byte[] encryptByPublicKey(String data, Key key) throws Exception { //对数据加密 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(data.getBytes()); } /** * 用私钥对象解密 * * @param data 加密后数据 * @param key 私钥对象 * @return byte[] 解密后数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, Key key) throws Exception{ //对数据解密 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(data); }}
测试
package cn.silence.encrypt;import java.security.Key;import java.util.Map;/** * Created by Silence on 2017/12/15. */public class main { public static void main(String[] args) throws Exception { String testString = "{\"data\":\"测试\"}"; //初始化密钥 Map<String, Key> map = RSACoder.initKey(); //获取公钥 String publicKey = RSACoder.getPublicKey(map); //获取私钥 String privateKey = RSACoder.getPrivateKey(map); /** * 公钥加密,私钥解密 */ byte[] encryptString = RSACoder.encryptByPublicKey(testString, publicKey); byte[] decryptString = RSACoder.decryptByPrivateKey(encryptString, privateKey); //输出结果 System.out.println(new String(decryptString)); /** * 私钥加密,公钥解密 */ encryptString = RSACoder.encryptByPrivateKey(testString.getBytes("UTF-8"), privateKey); decryptString = RSACoder.decryptByPublicKey(encryptString, publicKey); //输出结果 System.out.println(new String(decryptString)); /** * 验签 */ String signedData = RSACoder.sign(testString.getBytes(), privateKey); boolean is = RSACoder.verify(testString.getBytes(), publicKey, signedData); System.out.println(is); /** * 用无Base64的密钥加解密 */ encryptString = RSACoder.encryptByPublicKey(testString, RSACoder.getPublicKeyNoBase64(map)); decryptString = RSACoder.decryptByPrivateKey(encryptString, RSACoder.getPrivateKeyNoBase64(map)); System.out.println(new String(decryptString)); }}
总结
密钥出于安全性考虑可以Base64,否则可以直接存取;
鸣谢
非常感谢百度百科
阅读全文
0 0
- RSA 非对称加密
- RSA非对称加密
- RSA非对称加密
- RSA非对称加密
- RSA 非对称加密
- rsa非对称加密
- RSA非对称加密
- 非对称加密RSA
- RSA非对称加密
- 非对称加密 rsa
- Rsa非对称加密
- RSA非对称加密
- RSA非对称加密
- 非对称加密RSA
- 非对称加密--RSA
- 非对称加密------RSA
- 使用非对称RSA加密
- asp rsa 非对称加密
- sublime前端插件推荐让sublime变成webstorm
- Qt Quick Controls模块
- 嵌入式C编程中的全局变量重复声明问题
- 设计模式【工厂方法模式】
- javascript 之模块化篇
- 非对称加密------RSA
- 你写的代码,是别人的噩梦吗?
- Best Reward
- 知识 | 梯度下降训练法
- 【面试】算法面试复习总结
- onscroll的用法
- spring框架
- Markdown系列(4)- 你不知道的Markdown基础知识
- kafka技术白皮书