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#不能解密 但是我尝试了一下,发现是可以的,下面就是我尝试的代码,如果您有什么问题,我想看看, ...
随机推荐
- CComSafeArray
https://blog.csdn.net/tangaowen/article/details/6554640
- mysql 执行多线程临时方案
sqr::IDatabase *db=NULL;IDbConnection *conn = NULL;int main(int argc, char* argv[]) { db = GetDataba ...
- 改变yii2 $form最外层div样式
<?php $form = ActiveForm::begin([ 'options'=>['class' => 'form-horizontal row-border','enct ...
- SIM900 AT来电显示开启,一些代码
/*Note: this code is a demo for how to using gprs shield to send sms message, dial a voice call and ...
- EXT combobox 二级连动 清空store缓存数据
项目中有这样的一个需求,做一个连动操作,如图: 所属行业中的combobox中下拉框中的值会根据前一个选择框中的值动态去变化,这个其实非常好做,但不是我现在讨论的主要问题,主要问题是,当第二次选择了& ...
- gj12-1 协程和异步io
1 并发.并行.同步.异步.阻塞.非阻塞 并发.并行 并发是报一个时间段内有几个程序在同一个cpu上运行,但是任意时刻只有一个程序在cpu上运行.在一个时间段内某一个请求很快,能够响应的用户就越多,高 ...
- UVa 1572 Self-Assembly (构造+拓扑排序。。。。。)
题意:给定n个带标号的正方形,标号要么是一个大写字母加一个+或-,要么是00, 当且仅当大写字母相同并且符号相反时可以连接,问你给定的能不能拼成一个无限大的的东西. 析:说实话,真心没有看出来是拓扑排 ...
- spss-非参数检验-K多个独立样本检验( Kruskal-Wallis检验)案例解析
今天和大家一起探讨和分下一下SPSS-非参数检验--K个独立样本检验 ( Kruskal-Wallis检验). 还是以SPSS教程为例: 假设:HO: 不同地区的儿童,身高分布是相同的 H1: 不 ...
- 16)maven lifecycle
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html http://maven.apache.o ...
- 使用process_monitor.sh监控hadoop进程的crontab配置
可以从下列链接找到process_monitor.sh:https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh ...