RSA 数据加密解密
来源:互联网 发布:网络歌手小右个人 编辑:程序博客网 时间:2024/05/18 20:50
RSA 是一种非对称的数据加密算法,他有两对钥匙,分别为公钥和私钥,公钥加密只能用私钥解密,那相应的私钥加密,也只能由公钥解密。这样保证了一定的安全性。
RSA 的用处有两种:
- 是对数据的加密和解密,比如银行卡,身份证,手机号,等等这些比较敏感的信息,进行加密。
- 加签和验签,多用在需要公网传输数据的时候,包括https的核心原理也是这样的。
https的工作原理可以参考 https加密通信过程图解
show me the code
package com.netfinworks.mag.util.sign;import org.apache.commons.codec.binary.Base64;import java.io.UnsupportedEncodingException;import java.security.*;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.xml.bind.DatatypeConverter;/** * Created by mazhenhua on 2017/05/06. */public class RSATest { /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; private static byte[] h2b(String hex){ return DatatypeConverter.parseHexBinary(hex); } private static String b2h(byte[] bytes){ return DatatypeConverter.printHexBinary(bytes); } private static SecureRandom sr = new SecureRandom(); public static KeyPair newKeyPair(int rsabits) throws NoSuchAlgorithmException { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(rsabits, sr); return generator.generateKeyPair(); } public static byte[] pubKeyToBytes(PublicKey key){ return key.getEncoded(); // X509 for a public key } public static byte[] privKeyToBytes(PrivateKey key){ return key.getEncoded(); // PKCS8 for a private key } public static PublicKey bytesToPubKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException{ return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(bytes)); } public static PrivateKey bytesToPrivKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException{ return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(bytes)); } public static byte[] encryptWithPubKey(byte[] input, PublicKey key) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(input); } public static byte[] decryptWithPrivKey(byte[] input, PrivateKey key) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(input); } private static byte[] getContentBytes(String content, String charset) { if (charset == null || "".equals(charset)) { return content.getBytes(); } try { return content.getBytes(charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset); } } /** * * @param text 待验签数据 * @param sign 验签值 * @param publicKey 公钥 * @param charset 编码字符 * @return * @throws Exception */ public static boolean verify(String text, String sign, PublicKey publicKey, String charset) throws Exception { Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicKey); signature.update(getContentBytes(text, charset)); return signature.verify(Base64.decodeBase64(sign)); } /** * * @param text 待加签数据 * @param privateK 私钥 * @param charset 编码字符 * @return * @throws Exception */ public static String sign(String text, PrivateKey privateK, String charset) throws Exception { Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(getContentBytes(text, charset)); byte[] result = signature.sign(); return Base64.encodeBase64String(result); } public static void main(String[] args) throws Exception { KeyPair kp = newKeyPair(1<<11); // 2048 bit RSA; might take a second to generate keys PublicKey pubKey = kp.getPublic(); PrivateKey privKey = kp.getPrivate(); String plainText = "Dear Bob,\nWish you were here.\n\t--Alice"; byte[] cipherText = encryptWithPubKey(plainText.getBytes("UTF-8"),pubKey); System.out.println("cipherText: "+b2h(cipherText)); System.out.println("plainText:"); System.out.println(new String(decryptWithPrivKey(cipherText,privKey),"UTF-8")); }}
main方法中,只有加解密的,加签验签的方法我已经加上了。
这里用的秘钥对都是自己生成的2048位长度,一般情况下都是使用的都是被base64后的字符串,或者是购买的密钥对证书。这个密钥也可以自己用JDK生成,网上很多方法。
很多网站还在用1024为长度的秘钥,我听过很多同事1024长度的秘钥已经有人能够破解了。现在建议用2048为长度的秘钥。
秘钥长度越长加密的复杂度就越高,相应的破解起来就越困难,理论上当秘钥达到一定长度是不可能被破解的。
参考资料:stackoverflow
0 0
- RSA 数据加密解密
- RSA加密数据Ukey解密
- RSA 加密解密-不正确的数据2
- java使用RSA加密方式实现数据加密解密
- RSA加密、解密
- RSA加密解密
- 加密解密---------->RSA算法
- RSA 加密解密总结
- RSA加密解密-实例
- RSA简单加密解密
- RSA加密解密算法
- RSA加密解密算法
- java RSA加密解密
- Java RSA加密解密
- RSA加密解密操作
- RSA加密与解密
- Java RSA加密解密
- RSA加密解密
- 求字符串的子集
- Log4J入门教程(一) 入门例程
- react demo2 (JSX入门)
- 锁的种类
- SVM处理mnist字体库
- RSA 数据加密解密
- Android日常错误-----app按home键,再次点击图标直接进入APP,以及APP保活问题
- Linux命令中Ctrl+z、Ctrl+c和Ctrl+d的区别和使用
- 猜神童年龄
- 二叉树的链式存储,先序建树,以及4种遍历方式
- Kaldi学习笔记(二)
- Hdu 3401 题解 单调队列优化DP
- oracle分析函数系列之rank,dense_rank,row_number:实现排名策略
- WIN7 双系统安装