我用 Java 和 PHP 设置了两个程序来比较输出 (signature = finalStr) 和
签名的验证。为了获得可比较的结果,我对 RSA 密钥进行了硬编码
在这两个程序中,所以代码看起来有点奇怪。
为了获得更短的密钥字符串,我生成了不安全的 512 位 RSA 密钥 -
在生产环境中至少使用 2048 位密钥。
如您所见,这两个程序生成相同的签名:
finalStr: NEHC7o+mW34qoTNOwXRQIRfs80s/YhudzX0K4AGlFTeyyJcRhit9f03iw58Ww1Eo3zfkSrrz3411TZheVLHFnQ==
两个程序都可以验证签名为true。
这是Java代码:
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class MainSo {
public static void main(String[] args) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, InvalidKeySpecException {
System.out.println("https://stackoverflow.com/questions/62674669/converting-nodejs-or-java-signature-hashing-function-to-php");
// keys are sample rsa 512 keys
String privateKey1 = "-----BEGIN PRIVATE KEY-----\n" +
"MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqg8Hlhxm7LfqASjF\n" +
"KMce91anr2ViG/K8GQmk0HPMiw3Lh6DrGDGmsw2jUczwQTyv07qDwWwf+vaEiTdk\n" +
"jd1JxQIDAQABAkAOGbTtU2mNUyqJ8hF28hu1MnAw8N0TqCrEgLIzvoZFOTqvxPqc\n" +
"VaCuUs4Fm/J5x8gWLycsRmbBMeecIzvjzXY5AiEAtoZ4WSplvJbEHjiKhW+dRICc\n" +
"tSTcGaTf0v4vdfQTiGsCIQDug9wLUZDiSttbz2QlA3QthFX+UIu8fE/A/lGEjXnC\n" +
"jwIgcejRyrPO8jcVBdc7e7MAbvPk2Je8VLS0irTfYbmFRykCIQDCFsbu5vbxTlzm\n" +
"fwNNI1xc1b1sb3rmbHox4EHRjZaxfQIgEr2r53jmSRlyQfueo4nLZJhTGXdaJN8Z\n" +
"yoWwFsFqsiA=\n" +
"-----END PRIVATE KEY-----";
String publicKey1 = "-----BEGIN PUBLIC KEY-----\n" +
"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoPB5YcZuy36gEoxSjHHvdWp69lYhvy\n" +
"vBkJpNBzzIsNy4eg6xgxprMNo1HM8EE8r9O6g8FsH/r2hIk3ZI3dScUCAwEAAQ==\n" +
"-----END PUBLIC KEY-----";
// rsa key generation
// Remove markers and new line characters in private key
String realPrivateKey = privateKey1.replaceAll("-----END PRIVATE KEY-----", "")
.replaceAll("-----BEGIN PRIVATE KEY-----", "")
.replaceAll("\n", "");
byte[] priKey = Base64.getDecoder().decode(realPrivateKey);
PKCS8EncodedKeySpec specPri = new PKCS8EncodedKeySpec(priKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(specPri);
// Remove markers and new line characters in public key
String realPublicKey = publicKey1.replaceAll("-----END PUBLIC KEY-----", "")
.replaceAll("-----BEGIN PUBLIC KEY-----", "")
.replaceAll("\n", "");
byte[] pubKey = Base64.getDecoder().decode(realPublicKey);
X509EncodedKeySpec specPub = new X509EncodedKeySpec(pubKey);
PublicKey publicKey = kf.generatePublic(specPub);
String baseString = "Constructed base string";
//Signature sig = Signature.getInstance("RSA-SHA256");
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(privateKey); // Get private key from keystone
sig.update(baseString.getBytes());
byte[] signedData = sig.sign();
String finalStr = Base64.getEncoder().encodeToString(signedData);
System.out.println("finalStr: " + finalStr);
// verify signature
byte[] signedDataVerify = Base64.getDecoder().decode(finalStr);
Signature sigVerify = Signature.getInstance("SHA256withRSA");
sigVerify.initVerify(publicKey);
sigVerify.update(baseString.getBytes());
boolean verified = sigVerify.verify(signedDataVerify);
System.out.println("signature verified: " + verified);
}
}
这里是 PHP 代码:
<?php
// https://stackoverflow.com/questions/62674669/converting-nodejs-or-java-signature-hashing-function-to-php
$data = 'Constructed base string';
// sample 512 rsa keys
$privateKey1 = "-----BEGIN PRIVATE KEY-----\n" .
"MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqg8Hlhxm7LfqASjF\n" .
"KMce91anr2ViG/K8GQmk0HPMiw3Lh6DrGDGmsw2jUczwQTyv07qDwWwf+vaEiTdk\n" .
"jd1JxQIDAQABAkAOGbTtU2mNUyqJ8hF28hu1MnAw8N0TqCrEgLIzvoZFOTqvxPqc\n" .
"VaCuUs4Fm/J5x8gWLycsRmbBMeecIzvjzXY5AiEAtoZ4WSplvJbEHjiKhW+dRICc\n" .
"tSTcGaTf0v4vdfQTiGsCIQDug9wLUZDiSttbz2QlA3QthFX+UIu8fE/A/lGEjXnC\n" .
"jwIgcejRyrPO8jcVBdc7e7MAbvPk2Je8VLS0irTfYbmFRykCIQDCFsbu5vbxTlzm\n" .
"fwNNI1xc1b1sb3rmbHox4EHRjZaxfQIgEr2r53jmSRlyQfueo4nLZJhTGXdaJN8Z\n" .
"yoWwFsFqsiA=\n" .
"-----END PRIVATE KEY-----\n";
$publicKey1 = "-----BEGIN PUBLIC KEY-----\n" .
"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoPB5YcZuy36gEoxSjHHvdWp69lYhvy\n" .
"vBkJpNBzzIsNy4eg6xgxprMNo1HM8EE8r9O6g8FsH/r2hIk3ZI3dScUCAwEAAQ==\n" .
"-----END PUBLIC KEY-----\n";
$privateKey = openssl_pkey_get_private ($privateKey1);
$publicKey = openssl_pkey_get_public($publicKey1);
// create the signature
openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
echo 'finalStr (Base64):' . PHP_EOL . base64_encode($signature) . PHP_EOL;
// verify signature
$result = openssl_verify($data, $signature, $publicKey, "sha256WithRSAEncryption");
echo 'verified (0=false, 1=true): ' . $result;
?>