我正在植入支付宝API,到我的项目中。为了提出一些请求,我需要生成一个签名与RSA private.pem - public.pem。文档只显示了JAVA示例,但我需要用NodeJS实现它。因此,我尝试使用crypto.sign,但无法使其正常工作。
下面是JAVA代码:
const g = (content, privateKey, charset) => {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(priPKCS8);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(priKey);
signature.update(content.getBytes(charset));
byte[] signed = signature.sign();
return Base64.getEncoder().encodeToString(signed);
} catch (Exception e) {
throw new RuntimeException("the key's format maybe not right");
}
}
有没有人能帮我把这段代码转换成NodeJS代码。
以下是我的工作解决方案:
/**
* @param {*} // let parameters = new Map(); parameters.set("service", "alipay.overseas.secmerchant.maintain.queryStatus");
*/
signRSA: async (parameters) => {
let unnecessaryParams = Array.from(parameters.entries())
.filter(a1 => a1[1] === undefined || a1[1].length === 0 || a1[1] === "null")
.map(a1 => a1[0]);
unnecessaryParams.forEach(a1 => parameters.delete(a1));
let charset = ["_input_charset", "charset"].filter(a1 => parameters.has(a1)).map(a1 => parameters.get(a1))[0];
charset = charset === undefined ? "UTF-8" : charset;
//MD5,RSA,RSA2
let signContent = Array.from(parameters.entries())
.filter(a1 => {
return a1[0] !== "sign" && a1[0] !== "sign_type";
})
.sort((a1, a2) => a1[0].localeCompare(a2[0]))
.map(a1 => a1[0] + "=" + a1[1]).join("&");
let key = fs.readFileSync('./services/alipay/rsa_private_key.pem');
// let RSA_sign = r.sign_it(signContent, key, "RSA2")
let RSA_sign = crypto.createSign('RSA-SHA256')
RSA_sign.update(signContent)
let s1 = RSA_sign.sign(key, "base64")
parameters.set("sign", s1);
return Array.from(parameters.entries()).map(a1 => a1[0] + "=" + encodeURIComponent(a1[1])).join("&");
}
发布于 2020-04-07 19:55:23
我已经创建了这段代码的Node.js版本,它应该使用提供的私钥对内容进行签名。
我还创建了一个verifySignature函数来检查这一点,并用Java语言创建了等效的代码(使用您的代码作为模板),以确保我们在两种语言中得到相同的结果。
Node.js
const crypto = require("crypto");
// Sample keys I've generated
const privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAICFIt6pLMSNn9scI/h85V/DamtsFqfN4DB+VSPpGMAcwEByKVsiBzdX7JJsr8uquoVWEmFPwymxUVwIy+MOK03QEaQDns0W/SeVNXyWvDTO2w65vV9hIEO1VyiQiBA8n0yoQGfbn2KBnv7SggJDpy10cF3lx5SdHV96lF+qyBs7AgMBAAECgYAQEJRLQNpXt1xEB0B3zyTc05B53Qj38MQVS7VYx8pQOUfOxnZk7dv5DwSDSRKwYqbuA9RIVbAPhhqlZnQV7a9722QBFcEKLh6/65HCX248t/v6/x1kj9p6rcbLuFuakjKXs4AznWmb4YV2Flh9/qx9keUzdS5/UPJZVU2+grAAAQJBAO/3JjTRgiGQxEdA4MVpfs0lh/+gzbDszL1In5USAPKyGPDqYIktAfF3cBc7BKyK3kBenJi3S5Qv5R3u2Ly6H0cCQQCJG5oAvEt8JPL7ZyxHzdTP7+7hWXRGOyK2Ar0CO3fbg+SGls5liJY3HNHc0lrdyG1A+5Z6AKUNYCgfbOhqmeZtAkEA5CzhUoYJNDuAt7Q0RuLqZM2URPk1vU9d23qr68ajyiKZXrOuuaFnYKDOn/hJmHuvnAua4gggwLbOKSlNRB/CzwJAKedztBHYiELKuKeZ0wBHsJ3GRr2OWgCs5TAFEG+YfFDdQX1J66JJNuLqCTGJcAtXyOqb3QHhcCsZWDFy/1G2KQJBAKRnm7D0BHLOK37Xp3MxGva4tFP6VPdqjgIVBW3PM8BcwTcw8VML3kkFh2y0gJdLRxzFwDDJgfG6Cxp8i1gqB+4=";
const publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAhSLeqSzEjZ/bHCP4fOVfw2prbBanzeAwflUj6RjAHMBAcilbIgc3V+ySbK/LqrqFVhJhT8MpsVFcCMvjDitN0BGkA57NFv0nlTV8lrw0ztsOub1fYSBDtVcokIgQPJ9MqEBn259igZ7+0oICQ6ctdHBd5ceUnR1fepRfqsgbOwIDAQAB";
const content = "We are such stuff as dreams are made on, and our little life is rounded with a sleep";
const signature = signContent(content, base64KeyToPEM(privateKey, "PRIVATE"), "utf8");
console.log("Signature:", signature);
console.log("Verify signature:", verifySignature(content, base64KeyToPEM(publicKey, "PUBLIC"), signature, "utf8"));
function signContent(content, privateKey, encoding) {
const sign = crypto.createSign("SHA256");
sign.write(content, encoding);
sign.end();
return sign.sign(privateKey, "base64");
}
function verifySignature(content, publicKey, signature, encoding) {
const verify = crypto.createVerify("SHA256");
verify.write(content, encoding);
verify.end();
return verify.verify(publicKey, Buffer.from(signature, "base64"));
}
function base64KeyToPEM(base64Key, keyType) {
return [`-----BEGIN ${keyType} KEY-----`, ...splitStringIntoChunks(base64Key, 64), `-----END ${keyType} KEY-----`].join("\n");
}
function splitStringIntoChunks(input, chunkSize) {
const chunkCount = Math.ceil(input.length / chunkSize)
return Array.from( { length: chunkCount } ).map((v, chunkIndex) => input.substr(chunkIndex * chunkSize, chunkSize));
}Java
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;
public class DigitalSignature {
public static void main(String[] args)
{
try {
// Sample keys I've generated
final String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAICFIt6pLMSNn9scI/h85V/DamtsFqfN4DB+VSPpGMAcwEByKVsiBzdX7JJsr8uquoVWEmFPwymxUVwIy+MOK03QEaQDns0W/SeVNXyWvDTO2w65vV9hIEO1VyiQiBA8n0yoQGfbn2KBnv7SggJDpy10cF3lx5SdHV96lF+qyBs7AgMBAAECgYAQEJRLQNpXt1xEB0B3zyTc05B53Qj38MQVS7VYx8pQOUfOxnZk7dv5DwSDSRKwYqbuA9RIVbAPhhqlZnQV7a9722QBFcEKLh6/65HCX248t/v6/x1kj9p6rcbLuFuakjKXs4AznWmb4YV2Flh9/qx9keUzdS5/UPJZVU2+grAAAQJBAO/3JjTRgiGQxEdA4MVpfs0lh/+gzbDszL1In5USAPKyGPDqYIktAfF3cBc7BKyK3kBenJi3S5Qv5R3u2Ly6H0cCQQCJG5oAvEt8JPL7ZyxHzdTP7+7hWXRGOyK2Ar0CO3fbg+SGls5liJY3HNHc0lrdyG1A+5Z6AKUNYCgfbOhqmeZtAkEA5CzhUoYJNDuAt7Q0RuLqZM2URPk1vU9d23qr68ajyiKZXrOuuaFnYKDOn/hJmHuvnAua4gggwLbOKSlNRB/CzwJAKedztBHYiELKuKeZ0wBHsJ3GRr2OWgCs5TAFEG+YfFDdQX1J66JJNuLqCTGJcAtXyOqb3QHhcCsZWDFy/1G2KQJBAKRnm7D0BHLOK37Xp3MxGva4tFP6VPdqjgIVBW3PM8BcwTcw8VML3kkFh2y0gJdLRxzFwDDJgfG6Cxp8i1gqB+4=";
final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAhSLeqSzEjZ/bHCP4fOVfw2prbBanzeAwflUj6RjAHMBAcilbIgc3V+ySbK/LqrqFVhJhT8MpsVFcCMvjDitN0BGkA57NFv0nlTV8lrw0ztsOub1fYSBDtVcokIgQPJ9MqEBn259igZ7+0oICQ6ctdHBd5ceUnR1fepRfqsgbOwIDAQAB";
final String content = "We are such stuff as dreams are made on, and our little life is rounded with a sleep";
String signature = signContent(content, privateKey, "UTF-8");
System.out.println("Signature: " + signature);
System.out.println("verifySignature: " + verifySignature(signature, content, getPublicKeyFromBase64(publicKey), "UTF-8"));
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
private static PublicKey getPublicKeyFromBase64(String publicKeyBase64) throws Exception {
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)));
}
public static String signContent(String content, String privateKey, String charset) throws Exception
{
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(priPKCS8);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(priKey);
signature.update(content.getBytes(charset));
byte[] signed = signature.sign();
return Base64.getEncoder().encodeToString(signed);
} catch (Exception e) {
throw new RuntimeException("signContent: Exception occurred: " + e.getMessage());
}
}
public static Boolean verifySignature(String signatureBase64, String content, PublicKey publicKey, String charset) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(content.getBytes(charset));
return signature.verify(Base64.getDecoder().decode(signatureBase64));
}
}https://stackoverflow.com/questions/61073068
复制相似问题