RSA加密遇到问题了,求高手帮忙

J2EE 码拜 8年前 (2016-09-23) 1645次浏览
在做支付宝的支付接口,是用来给客户端返回需要使用的参数,以url的形式返回,客户端需要用SDK来调用支付宝接口。但是在调用支付宝给的实例的方法的时候,加密那一块总是报错。代码如下:
调用签名:
/**
加密签名信息SDK
* @return
*/
public String getSDKSign() {
Map<String, String> params = new HashMap<String, String>();
params.put(“partner”, partner);
params.put(“seller_id”, sellerEmail);
params.put(“out_trade_no”, outTradeNo);
params.put(“subject”, subject);
params.put(“body”, body);
params.put(“total_fee”, orderAmount);
params.put(“notify_url”, notifyUrl);
params.put(“service”, service);
params.put(“payment_type”, paymentType);
params.put(“_input_charset”, inputCharset);
params.put(“it_b_pay”, timeoutRule);
params.put(“show_url”, showUrl);
//除去数组中的空值和签名参数
Map<String, String> sPara = AlipayVerifyUtils.paraFilter(params);
String sign = RSAEncrypt.sign(createLinkString(sPara),key,”utf-8″);
return sign;
}
签名方法:
RSA签名
* @param content 待签名数据
* @param privateKey 商户私钥
* @param input_charset 编码格式
* @return 签名值
*/
public static String sign(String content, String privateKey, String input_charset)
{
try
{
PKCS8EncodedKeySpec priPKCS8  = new PKCS8EncodedKeySpec( Base64.decode(privateKey));
KeyFactory keyf  = KeyFactory.getInstance(“RSA“);
PrivateKey priKey  = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update( content.getBytes(input_charset) );
byte[] signed = signature.sign();
return Base64.encode(signed);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
Base64方法:
public static byte[] decode(String encoded) {
if (encoded == null) {
return null;
}
char[] base64Data = encoded.toCharArray();
// remove white spaces
int len = removeWhiteSpace(base64Data);
if (len % FOURBYTE != 0) {
return null;// should be divisible by four
}
int numberQuadruple = (len / FOURBYTE);
if (numberQuadruple == 0) {
return new byte[0];
}
byte decodedData[] = null;
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
int i = 0;
int encodedIndex = 0;
int dataIndex = 0;
decodedData = new byte[(numberQuadruple) * 3];
for (; i < numberQuadruple – 1; i++) {
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
|| !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) {
return null;
} // if found “no data” just return null
b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2];
b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
}
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
return null;// if found “no data” just return null
}
b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2];
d3 = base64Data[dataIndex++];
d4 = base64Data[dataIndex++];
if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
if (isPad(d3) && isPad(d4)) {
if ((b2 & 0xf) != 0) // last 4 bits should be zero
{
return null;
}
byte[] tmp = new byte[i * 3 + 1];
System.arraycopy(decodedData, 0, tmp, 0, i * 3);
tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
return tmp;
} else if (!isPad(d3) && isPad(d4)) {
b3 = base64Alphabet[d3];
if ((b3 & 0x3) != 0) // last 2 bits should be zero
{
return null;
}
byte[] tmp = new byte[i * 3 + 2];
System.arraycopy(decodedData, 0, tmp, 0, i * 3);
tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
return tmp;
} else {
return null;
}
} else { // No PAD e.g 3cQl
b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
}
return decodedData;
}
使用的生成私钥的命令:
RSA密钥生成命令
生成RSA私钥
openssl>genrsa -out rsa_private_key.pem 1024
生成RSA公钥
openssl>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
将RSA私钥转换成PKCS8格式
openssl>pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
当作String privateKey的值是:
–BEGIN RSA PRIVATE KEY–
MIICXgIBAAKBgQDr9YMFdzhgZT73yDmebur3cY85pF4oHmkJJTEfml14YBtJmOUk
wpzveim+ZDzJzjouyykNP8D943LZ/YPNbICqt2atslllXGcnkSSGOMMVktMZAyNa
ubqEHumfPpkiHZ47p9wvmOCUJapr3a020gORm8Nc6PtEVYA4Ymcx3pXBjQIDAQAB
AoGBAOOTyse1wfkvDXlccz48ioEX1OTqhCm7kuDQLz3k22vjfc4RGkjHLyfGMobA
FOUq83D4X2K478Gv4rEfU0UI9lpXKlo6/7jStxkDYWfPcejYalCJsXG9bX7G4Leb
D6CP7UztDlxhkhAWdtOm9Oie9TMzJ/+capgJBvnukTvDomY9AkEA9f8Zfr5WUZN7
XHMUbH08ApyXWVbq8p4l1veXl5uemmQgrMlVzpZcmoLT3fQvErApRQbE0v3Fv/jP
By+u3ZmajwJBAPWN61AU8zE85v+htIoXjnlWabxKjLEPtPy3ujVBc212aEMyJM0z
OecSL0cJtpCFISU+hEuvXfdrM/yM101gYCMCQDcyKxVOPe4F6ose4zlIjFuFqUwJ
faQ8qf7nBSOmblr0FoTOlCtLf7HHoyRNMva9gjUTxLwW5vUhLcrN/y2H1q8CQQCU
DR9lx1vhwhCc7IiIAi/65KkXx/MQBqJfBP+WgIHx68RtT1x1BH/S3Fn5ANg8Rqh3
ZjwpzfBf7xkHGnvtwT/1AkEAzI5P8wrsMnbJg4h5CiJzYqhYWYyE/tdxFQNIhVPO
POLAne5FL+f13MtqaErBmjsYZkwSuxPjhHCFoL/ByHDh6w==
–END RSA PRIVATE KEY–
报的错误信息如下:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
at com.kuapinmall.app.api.util.RSAEncrypt.sign(RSAEncrypt.java:33)
at com.kuapinmall.app.api.domain.vo.PayInfo.getSDKSign(PayInfo.java:131)
at com.kuapinmall.app.core.controller.OrderInfoController.orderPay(OrderInfoController.java:1247)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:177)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:434)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351)
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75)
at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316)
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213)
解决方案

5

百度java.security.InvalidKeyException
随便找了一个http://ksgimi.iteye.com/blog/1584716
能否能解决你问题?

10

私钥:只取
–BEGIN RSA PRIVATE KEY–
–END RSA PRIVATE KEY–

中间的部分

10

好像可以找支付宝的技术支持

10

base64 用现成的方法 假如是jdk1.8, 就包含了BASE64的处理类

5

下载个支付宝的sdk,加密、解密都给你写好了,干嘛还要本人写呢

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明RSA加密遇到问题了,求高手帮忙
喜欢 (0)
[1034331897@qq.com]
分享 (0)