我已经创建了此代码的 Node.js 版本,它应该使用提供的私钥对内容进行签名。
我还创建了一个 verifySignature 函数来检查这一点,并在 Java 中创建了等效代码(使用您的代码作为模板),以确保我们在两种语言中获得相同的结果。
节点.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));
}
爪哇
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));
}
}