RSA加密/解密 Decryption error异常解决
RSA加密/解密 Decryption error异常解决
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
public class RSATest {
private static final String ALGORITHM = "RSA";
private static final String PUBLICK_EY = "PUBLICK_EY";
private static final String PRIVATE_KEY = "PRIVATE_KEY";
/**
* 加密算法
*/
private static final String CIPHER_DE = "RSA";
/**
* 解密算法
*/
private static final String CIPHER_EN = "RSA";
/**
* 密钥长度
*/
private static final Integer KEY_LENGTH = 1024;
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 生成秘钥对,公钥和私钥
*
* @return
* @throws NoSuchAlgorithmException
*/
public static Map<String, Object> genKeyPair() throws NoSuchAlgorithmException {
Map<String, Object> keyMap = new HashMap<String, Object>();
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
keyPairGenerator.initialize(KEY_LENGTH); // 秘钥字节数
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
keyMap.put(PUBLICK_EY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 公钥加密
*
* @param data
* @param publicKey
* @return
* @throws InvalidKeySpecException
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
// 得到公钥
byte[] keyBytes = Base64.decodeBase64(publicKey.getBytes());
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
Key key = keyFactory.generatePublic(x509EncodedKeySpec);
// 加密数据,分段加密
Cipher cipher = Cipher.getInstance(CIPHER_EN);
cipher.init(Cipher.ENCRYPT_MODE, key);
int inputLength = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
while (inputLength - offset > 0) {
if (inputLength - offset > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offset, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offset, inputLength - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* 私钥解密
*
* @param data
* @param privateKey
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception {
// 得到私钥
byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes());
PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
Key key = keyFactory.generatePrivate(pKCS8EncodedKeySpec);
// 解密数据,分段解密
Cipher cipher = Cipher.getInstance(CIPHER_DE);
cipher.init(Cipher.DECRYPT_MODE, key);
int inputLength = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
byte[] tmp;
while (inputLength - offset > 0) {
if (inputLength - offset > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offset, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offset, inputLength - offset);
}
// out.write(cache, 0, cache.length);
out.write(cache);
i++;
offset = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 获取公钥
*
* @param keyMap
* @return
*/
public static String getPublicKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PUBLICK_EY);
String str = new String(Base64.encodeBase64(key.getEncoded()));
return str;
}
/**
* 获取私钥
*
* @param keyMap
* @return
*/
public static String getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
String str = new String(Base64.encodeBase64(key.getEncoded()));
return str;
}
public static void main(String[] args) throws Exception {
Map<String, Object> keyMap = RSATest.genKeyPair();
String publicKey = RSATest.getPublicKey(keyMap);
String privateKey = RSATest.getPrivateKey(keyMap);
System.out.println("公钥:" + publicKey);
System.out.println("私钥:" + privateKey);
// 公钥加密
String sourceStr = "<REQ><HEAD><ReqCode>WDIS</ReqCode><MsgNo>500</MsgNo><MsgId>20171113123408</MsgId><MsgRef>20171113123408</MsgRef><Teller>00000951</Teller><BchCde>800000000</BchCde><WorkDate>20171113</WorkDate><WorkTime>123408</WorkTime></HEAD><MSG><ApplSeq>1666645</ApplSeq><AppAdvice>同意</AppAdvice><AppConclusion>10</AppConclusion><ApptList><Result><ApptTyp>01</ApptTyp><CustName>林羽凡</CustName><IdTyp>20</IdTyp><IdNo>350521196211216597</IdNo><ApptStartDate>1962-11-21</ApptStartDate><ApptAge>55</ApptAge><CrtBch>800000001</CrtBch><CrtDt>2017-11-13</CrtDt><IndivInfo><IndivSex>10</IndivSex><IndivMarital>20</IndivMarital><IndivEdu>10</IndivEdu><IndivDegree>4</IndivDegree><RegProvince>110000</RegProvince><RegCity>110100</RegCity><LiveInfo>10</LiveInfo><LiveProvince>110000</LiveProvince><LiveCity>110100</LiveCity><LiveArea>110105</LiveArea><LiveAddr>北京市市辖区朝阳区xxxxxxx</LiveAddr><LiveZip>100000</LiveZip><LiveMj>299.66</LiveMj><LocalResid>10</LocalResid><IndivMobile>13522015858</IndivMobile><PositionOpt>10</PositionOpt><IndivEmpName>山东科技有限公司</IndivEmpName><IndivEmpTyp>Z</IndivEmpTyp><IndivMthInc>500000.0</IndivMthInc><MailOpt>A</MailOpt><MailProvince>110000</MailProvince><MailCity>110100</MailCity><MailArea>110105</MailArea><MailAddr>北京市市辖区朝阳区xxxxxxx</MailAddr><IndivProfsn>00</IndivProfsn><IndivIndtryPaper>Q</IndivIndtryPaper><IndivPro>1</IndivPro><PptyLive>Y</PptyLive></IndivInfo><ExtInfo><SpouseName>黄海涛</SpouseName><SpouseIdTyp>20</SpouseIdTyp><SpouseIdNo>110105198310200112</SpouseIdNo><SpouseMobile>13589565487</SpouseMobile></ExtInfo><RelList><Result><RelName>黄海涛</RelName><RelMobile>13589565487</RelMobile><RelRelation>06</RelRelation></Result><Result/></RelList></Result><Result><ApptRelation>06</ApptRelation><ApptTyp>02</ApptTyp><CustName>黄海涛</CustName><IdTyp>20</IdTyp><IdNo>110105198310200112</IdNo><ApptStartDate>1983-10-20</ApptStartDate><ApptAge>34</ApptAge><CrtBch>800000001</CrtBch><CrtDt>2017-11-13</CrtDt><IndivInfo><IndivSex>20</IndivSex><IndivMarital>20</IndivMarital><IndivDegree>0</IndivDegree><LiveAddr>北京市市辖区朝阳区xxxxxxx</LiveAddr><LiveMj>299.66</LiveMj><LocalResid>10</LocalResid><IndivMobile>13581829258</IndivMobile><PositionOpt>50</PositionOpt><IndivEmpName>个体</IndivEmpName><IndivEmpTyp>Z</IndivEmpTyp><MailOpt>A</MailOpt><MailAddr>北京市市辖区朝阳区xxxxxxx</MailAddr><PptyLive>Y</PptyLive></IndivInfo><ExtInfo><SpouseName>林羽凡</SpouseName><SpouseIdTyp>20</SpouseIdTyp><SpouseIdNo>350521196211216597</SpouseIdNo><SpouseMobile>135xxxxxxxx</SpouseMobile></ExtInfo><RelList><Result><RelName>黄海涛</RelName><RelMobile>135xxxxxxxx</RelMobile><RelRelation>06</RelRelation></Result></RelList></Result></ApptList><HouInfo><Location>朝阳区xxxxx</Location><HouseArea>299.66</HouseArea><CompDate>2009-01-01</CompDate><PropRight>12</PropRight><HouseKindList>01</HouseKindList><HouseClass>01</HouseClass><HouseType>09</HouseType><HouseFrameSign>99</HouseFrameSign><HouseCertKind>03</HouseCertKind><PptyProvince>110000</PptyProvince><PptyCity>110100</PptyCity><PptyArea>110105</PptyArea><PptyAddr>朝阳区xxxxx</PptyAddr><OwnerName>林羽凡</OwnerName><HouseCertNo>北京房权证朝字第907946号</HouseCertNo></HouInfo><GurtInfo><gurtAmt>2.0E7</gurtAmt><collateralValue>2.0E7</collateralValue><gurtStartDt>2017-11-02</gurtStartDt><gurtEndDt>2020-11-02</gurtEndDt><gurtSignDt>2017-11-02</gurtSignDt><collInd>Y</collInd><regSts>02</regSts><mortgagorTyp>01</mortgagorTyp><rightCertTyp>01</rightCertTyp><rightCertNo>京(2017)朝不动产证明第0075996号</rightCertNo><custName>林羽凡</custName><mortgageType>01</mortgageType><isRent>N</isRent><obligorName>林羽凡</obligorName></GurtInfo><ApplInfo><ApplCde>201711131200000131495</ApplCde><ApplSeq>1666645</ApplSeq><IdTyp>20</IdTyp><IdNo>350521196211216597</IdNo><CustName>林羽凡</CustName><ProPurAmt>2.0E7</ProPurAmt><Purpose>OTH</Purpose><AppOrigin>03</AppOrigin><DocChannel>SYS001</DocChannel><ApplyDt>2017-10-27</ApplyDt><FstPct>0</FstPct><FstPay>0</FstPay><ApplyAmt>2.0E7</ApplyAmt><ApprvAmt>2.0E7</ApprvAmt><ApplyTnr>36</ApplyTnr><ApplyTnrTyp>M</ApplyTnrTyp><ApprvTnr>36</ApprvTnr><ApprvTnrTyp>M</ApprvTnrTyp><LoanTyp>ZYYH002</LoanTyp><MtdCde>LM004</MtdCde><LoanFreq>1M</LoanFreq><MtdMode>RV</MtdMode><PriceIntRat>0.07799998999999999</PriceIntRat><CrtDt>2017-11-02</CrtDt><TypGrp>04</TypGrp><GutrOpt>20</GutrOpt><CrtBch>800000001</CrtBch><CrtBchInd>N</CrtBchInd><RepcOpt>NYF</RepcOpt><DueDayOpt>2</DueDayOpt><DueDay>21</DueDay><Form>04</Form></ApplInfo><MtdList><Result><MtdCde>LM004</MtdCde><MtdTyp>04</MtdTyp><LoanInstal>36</LoanInstal><ApplMtdRateTyp>1</ApplMtdRateTyp><ApplMtdRateFloat>64.2105</ApplMtdRateFloat></Result></MtdList><AcctList><Result><ApplAcKind>01</ApplAcKind><ApplAcTyp>01</ApplAcTyp><RpymAcBank>105100000017</RpymAcBank><RpymAcNam>于三</RpymAcNam><RpymAcNo>6217000010039470748</RpymAcNo><RpymIdTyp>20</RpymIdTyp><RpymMethod>1</RpymMethod></Result><Result><ApplAcKind>02</ApplAcKind><ApplAcTyp>01</ApplAcTyp><RpymAcBank>105100000017</RpymAcBank><RpymAcNam>林羽凡</RpymAcNam><RpymAcNo>5522450010194467</RpymAcNo><RpymIdTyp>20</RpymIdTyp><RpymIdNo>350521196211216597</RpymIdNo><RpymMethod>1</RpymMethod></Result></AcctList></MSG></REQ>";
System.out.println("加密前:" + sourceStr);
byte[] encryptStrByte = RSATest.encryptByPublicKey(sourceStr.getBytes(), publicKey);
byte[] btt = Base64.encodeBase64(encryptStrByte);
String encryptStr = new String(btt);
System.out.println("加密后:" + encryptStr);
System.out.println("长度:" + encryptStr.length());
// 私钥解密
byte[] decryptStrByte = RSATest.decryptByPrivateKey(Base64.decodeBase64(Base64.encodeBase64(encryptStrByte)), privateKey);
String sourceStr_1 = new String(decryptStrByte);
System.out.println("解密后:" + sourceStr_1);
}
}
密钥长度修改为2048位时,报以下错误:
Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
at sun.security.rsa.RSAPadding.unpad(Unknown Source)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2223)
at com.caxs.esign.util.MYtest.decryptByPrivateKey(MYtest.java:117)
at com.caxs.esign.util.MYtest.main(MYtest.java:175)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
这是由于最大解密长度不正确导致报错,MAX_DECRYPT_BLOCK应等于密钥长度/8(1byte=8bit),所以当密钥位数为2048时,最大解密长度应为256.
private static final int MAX_DECRYPT_BLOCK = 128;RSA加密/解密 Decryption error异常解决的更多相关文章
- 最通俗易懂的RSA加密解密指导
前言 RSA加密算法是一种非对称加密算法,简单来说,就是加密时使用一个钥匙,解密时使用另一个钥匙. 因为加密的钥匙是公开的,所又称公钥,解密的钥匙是不公开的,所以称为私钥. 密钥 关于RSA加密有很多 ...
- 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输
Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...
- C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...
- C# Java间进行RSA加密解密交互
原文:C# Java间进行RSA加密解密交互 这里,讲一下RSA算法加解密在C#和Java之间交互的问题,这两天纠结了很久,也看了很多其他人写的文章,颇受裨益,但没能解决我的实际问题,终于,还是被我捣 ...
- Java使用RSA加密解密签名及校验
RSA加密解密类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ...
- 【转】 java RSA加密解密实现
[转] java RSA加密解密实现 该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detai ...
- iOS使用Security.framework进行RSA 加密解密签名和验证签名
iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...
- openssl evp RSA 加密解密
openssl evp RSA 加密解密 可以直接使用RSA.h 提供的接口 如下测试使用EVP提供的RSA接口 1. EVP提供的RSA 加密解密 主要接口: int EVP_PKEY_encryp ...
- Cryptopp iOS 使用 RSA加密解密和签名验证签名
Cryptopp 是一个c++写的功能完善的密码学工具,类似于openssl 官网:https://www.cryptopp.com 以下主要演示Cryptopp 在iOS上的RSA加密解密签名与验证 ...
随机推荐
- float元素浮动后高度不一致导致错位的解决办方法
换行开始的第一个元素clear:left;即可 例如 四列时应该时第5个,9个...加clear:left; .row .col-lg-3:nth-child(4n+1),.row .col-md- ...
- php-5.6.26源代码 - PHP文件汇编成opcode(require、include的差异)
文件 php-5.6.26/Zend/zend_language_scanner.c ZEND_API zend_op_array *compile_file(zend_file_handle *fi ...
- PHP开发环境搭建一:PHP集成环境XAMPP 的安装与配置
1. XMAPP简介 XAMPP(Apache+MySQL/MariaDB+PHP+Perl)开头的X代表X-OS,代表可以在任何常见操作系统下使用,包括Windows.Mac.Linux,开源平台. ...
- PLC状态机编程第六篇-优化PLC程序生成
还记得第一篇博客中,我们在状态机中手写上升沿来处理有别于传统的一键启停程序,那个手写的上升沿就是优化手段.stateflow状态机是带事件的,事件本身支持上升沿和下降沿等事件,在这里,如果我们选择用事 ...
- 学习Pytbon第十天 函数2 内置方法和匿名函数
print( all([1,-5,3]) )#如果可迭代对象里所有元素都为真则返回真.0不为真print( any([1,2]) )#如果数据里面任意一个数据为真返回则为真a= ascii([1,2, ...
- python scrapy实战糗事百科保存到json文件里
编写qsbk_spider.py爬虫文件 # -*- coding: utf-8 -*- import scrapy from qsbk.items import QsbkItem from scra ...
- gcc常用语法
1. gcc -E source_file.c-E,只执行到预编译.直接输出预编译结果. 2. gcc -S source_file.c -S,只执行到源代码到汇编代码的转换,输出汇编代码. 3. g ...
- 总结 Date 2017.09.23
总结 Date 2017.09.23 <1>统计数字 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计 ...
- 笔记-python-redis接口
笔记-python-redis接口 1. python 与redis接口 redis是redis数据库的python接口包,为python提供的redis的调用接口. 注:文档内容主要基于h ...
- P2344 奶牛抗议
P2344 奶牛抗议 题目背景 Generic Cow Protests, 2011 Feb 题目描述 约翰家的N 头奶牛正在排队游行抗议.一些奶牛情绪激动,约翰测算下来,排在第i 位的奶牛的理智度为 ...