RSA的JAVA实现 及javax.crypto.IllegalBlockSizeException
一、背景
最近工作中涉及到RSA加密的相关需求任务,之前对加密算法了解不多,开发过程中遇到了一些坑记录一下。
二、RSA原理
RSA加密是非对称加密,公开私钥,保留私钥。通信时数据通过公开的公钥加密,接收方用私钥解密,达到安全传输的目的。RSA算法原理在这就不详述了,放个链接 https://blog.csdn.net/raalghul/article/details/51883354
三、JAVA实现
公钥和私钥 都是由 两个数的组合构成,这样储存不太方便。 用base64将PublicKey 和PrivateKey对象 转为公钥、私钥 字符串。
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
generator.initialize(2048, new SecureRandom());
KeyPair keyPair = generator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
String pubKey = new String(Base64.encodeBase64(publicKey.getEncoded()));
System.out.println("公钥:"+pubKey);
PrivateKey privateKey = keyPair.getPrivate();
String priKey = new String(Base64.encodeBase64(privateKey.getEncoded()));
System.out.println("私钥:"+priKey);
在加密解密的过程中需要的仍是 PublicKey 和PrivateKey对象, 需要将 公钥、私钥字符串转换为 PublicKey 和PrivateKey对象 来实现加密 解密。
//公钥string 转publicKey对象
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = (new sun.misc.BASE64Decoder()).decodeBuffer(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
//公钥string 转publicKey对象
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = (new sun.misc.BASE64Decoder()).decodeBuffer(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
其他部分代码贴出,如果不注意编码问题会抛出javax.crypto.IllegalBlockSizeException,在代码中标出
public static PrivateKey getPrivateKey(String key) throws Exception{
byte[] keyBytes;
keyBytes = (new sun.misc.BASE64Decoder()).decodeBuffer(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
//加密
public static byte[] encrypt(byte[] content, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(content);
}
/**
* byte[] b1 byte[] b2 byte[] b1 String
* String data----getBytes(默认编码)-----公钥加密(ISO字符集,使用其他字符集数据丢失)---------私钥解密----------new String(默认编码)----String data
*
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
generator.initialize(2048, new SecureRandom());
KeyPair keyPair = generator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
String pubKey = new String(Base64.encodeBase64(publicKey.getEncoded()));
System.out.println("公钥:"+pubKey);
PrivateKey privateKey = keyPair.getPrivate();
String priKey = new String(Base64.encodeBase64(privateKey.getEncoded()));
System.out.println("私钥:"+priKey);
//公钥加密 此时的getBytes() 的编码 为默认 应该和最后的 new String() 的编码一样
byte[] encryptedBytes = encrypt(data.getBytes(), publicKey);
//将密文字节数组转String时 不使用ISO编码 可能导致数据丢失 解密失败
//如果下面两句 没有指明编码,或者使用其他编码,会导致数据的错误,导致字节数组b1长度超出限制, 报出异常javax.crypto.IllegalBlockSizeException,具体原因可能是因为在公钥加密时使用的字符集问题。
String s1 = new String(encryptedBytes,"ISO8859-1");
byte[] b1 = s1.getBytes("ISO8859-1");
//解密
byte[] decryptedByte = decrypt(b1, privateKey);
System.out.println("解密后:"+new String(decryptedByte));
}
public static byte[] decrypt(byte[] content, PrivateKey privateKey) throws Exception{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(content);
}
}
运行结果:

欢迎大家关注我的个人微信订阅号:Java从零单排 分享学习资料,交流学习经验~

RSA的JAVA实现 及javax.crypto.IllegalBlockSizeException的更多相关文章
- javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher--转载
原文地址:http://songjianyong.iteye.com/blog/1571029 /** * AESHelper.java * cn.com.songjy.test * * Functi ...
- Android AES加密报错处理:javax.crypto.IllegalBlockSizeException: error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
一.问题说明 今天写AES加/解密功能的apk,设想是四个控件(测试用的,界面丑这种东西请忽略) 一个编缉框----用于输入要加密的字符串 一个文本框----用于输出加密后的字符串,和加密后点击解密按 ...
- url请求时,参数中的+在服务器接收时为空格,导致AES加密报出javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
报错的意思的是使用该种解密方式出入长度应为16bit的倍数,但实际的错误却不是这个,错误原因根本上是因为在http请求是特殊字符编码错误,具体就是base64生成的+号,服务器接收时成了空格,然后导致 ...
- java rsa 解密报:javax.crypto.BadPaddingException: Decryption error
Exception in thread "main" javax.crypto.BadPaddingException: Decryption error at sun.se ...
- Liunx-https-java.lang.NoClassDefFoundError: javax/crypto/SunJCE_b
错误信息: java.lang.NoClassDefFoundError: javax/crypto/SunJCE_b at javax.crypto.KeyGenerator.a(DashoA13* ...
- Unable to execute 'doFinal' with cipher instance [javax.crypto.Cipher@4e025e0a]
org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with cipher instance [javax.cry ...
- AES算法,DES算法,RSA算法JAVA实现
1 AES算法 1.1 算法描述 1.1.1 设计思想 Rijndael密码的设计力求满足以下3条标准: ① 抵抗所有已知的攻击. ② 在多个平台上速度快,编码紧凑. ③ 设计 ...
- Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)
MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明 ...
- C# RSA和Java RSA互通
今天调查了C# RSA和Java RSA,网上很多人说,C#加密或者java加密 ,Java不能解密或者C#不能解密 但是我尝试了一下,发现是可以的,下面就是我尝试的代码,如果您有什么问题,我想看看, ...
随机推荐
- org.apache.commons札记
StringUtils.isBlank(null); //trueStringUtils.isBlank(""); //trueStringUtils.isBlank(" ...
- 2018.08.22 NOIP模拟 or(线段树)
or [描述] 构造一个长度为 n 的非负整数序列 x,满足 m 个条件,第 i 个条件为x[li] | x[li+1] | - | x[ri]=pi. [输入] 第一行两个整数 n,m.接下来 m ...
- 2018.07.17 HAOI2016 找相同字符(SAM)
传送门 就是给两个字符串,让你求公共字串的个数. 本来大佬们都是用的广义后缀自动机,但我感觉后缀自动机已经可以做这道题了.我们对其中一个字串建出后缀自动机,然后用另外一个后缀自动机在上面统计贡献即可. ...
- C语言之接收方向键指令让屏幕上的输出能移动
首先,需要了解一下控制台坐标 #include <stdio.h> #include <stdlib.h> #include <conio.h> main() { ...
- myeclipse新建jsp文件时弹出默认模板,怎么改成自己修改后的
(1)打开Window——Preferences (2)选择MyEclipse——Filed andEditors——JSP——JSP Source——Templates 看到右边的New Jsp编辑 ...
- (最小生成树)Jungle Roads -- HDU --1301
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1301 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- The First Android App----Starting Another Activity
To respond to the button's on-click event, open the activity_main.xml layout file and add the androi ...
- hdu 5685 Problem A (逆元)
题目 题意:H(s)=∏i≤len(s)i=1(Si−28) (mod 9973),求一个字符串 子串(a 位到 b 位的)的哈希值.这个公式便是求字符串哈希值的公式,(字符的哈希值 = 字符的ASC ...
- poj2462
看八戒在做这个题,我也做了做.. 坑很多,还是要注意细节.不得不吐槽,难道又到了计算几何只能套模板否则就一串WA的情况了么! 要不是八戒做出来了,这题我估计我也就扔到这里了..哥不服啊~所以得做出来! ...
- JdbcTemplate详解
1.JdbcTemplate操作数据库 Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中.同时,为了支 ...