OpenJDK 12 、PHP 7.3 测试交叉验证都通过。
// 原文
$data = '二〇二〇年四月四日 01:43:37';
// 私钥
$private = <<
-----BEGIN RSA PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCow6pxwoAIFXWs
ZY3QMoUmB4uAYk0cAROITeCLROpzwRDtcXRDJ3TP/LrwgviTlmPD/VAtxa01eW7+
xmCUCY7IuaG9UmRAF7q8RXQ+T74ce8zSF6KIWRbWv+DOq860zCmaa9zr5DBHgf5X
mwC6/SqBhQlE7WxrecNOJC7Qx5o1V/LhZ5hAP5nxg6zpoSvTMZitiQSRVuenqotP
t0iD8b4TRcX7siNGIE2mo7xoCnjJ7Vv3iuLi6kczfpH5WoB/k54hZncZPc/wN4m4
SWY4f1uoDr2XtkCDNAODuhu7LMz1Yvk7yRsyX7NwopmLHzhtjdSOSPnJszTQUkNa
+8DCSxJhAgMBAAECggEAbxJgUoDdfPSKvw0Tmcw2P8JFeRi5gU3gChyfRWn1GHwf
5PZ/u1bzlZPTgUnhylj3jl1g8M8iYYhrmfj8RVJJDCjIn27jlh9IAnN/vycCi4Kb
Wka97RkdY/djQQJoiCu60exduU80y0tuF0Bn6amH2Tiy0g+lBNNdzEcaHMTR5HrN
PS7wRCnU0i3aIZbGSfFT6EHQES5FE2q3hTrySrv4cqR2Jnk+UJPYMyl7/cgc/X7K
1cHCVpHmahhgxzXK2KBoOs2fmLcpHvlxu8roJm2OWxUDAoZFKtP5W6j0lbIl3afb
OJFjpH1SLOP55lAMGAU65Ili68yVWWQuJi+h23dDcQKBgQDR4ZKK8AvsWHSHIcuh
6/bBkKSXCLatZhqXE5sjaQy1syzXtLQ1JDYilDgorpvmqOfwClScF/eQLTYO+qM5
zQEfZpMjciLiywAvRCRFKlUSOE4jivfsMZLsZ617QSUMrxXRKlUXNMOEDP/wE5p+
LiaxORGWMuKJYavfabnmeEnH3QKBgQDN2SblEQok5+Q6kx5twrIJUhKeexLwtDHV
ybObO95iYMTCjbfxxA48w7jmJl1cPADqNINeDPOHNIl16RQ4UHH6MO32FVoHlei9
AtVqKxCpBiJvl7T7vg0n8Zr3uCANVmexdsSnq6DbqTrXCPufo9vmfkScGjK3lmgA
xqyJUkouVQKBgGteobBQQ1lCm0JySJFqfI7jpz/Y5lNo05uMHSaNXEIsCnnDaRly
j/s6pkwxn3Ht4NHNByHfpPduGaSqFgzA0p00xXsxraUmQs7rZj63/FNY2KiYNGLx
rX8hPv+6APEvNNMPe/5mMMuCNwCjlrqMc6DgWB3lpDyx6dJebQr5aI1FAoGAJLrw
s8L8mmU+Vi1WKqOo/PzGEb1IPecJVWpuP+7I2akGsuhywBMJr1IFNhv2YLTcPO4t
2qRY9/Ep7f4u+3VvQQNmEpjwvZXEN6W/yvfwOxi7IEpjot/gnRYBXt5d6cNXMVVN
9dUsGMXzl9ckfvHQFSrGt0v9bMDLwgexVbd3QRkCgYEAzTVg+3hY9lt1cdrwklOs
Yfw3K33lq+Ip8RZ7WjeuO6W2Fuvh/MHEBxnwcPEZSKIhOpOV2VdYQo80uqinE4il
4IQqhf2qFOshGHrOspDbJUgtuVH5JkmQDeh5yT5+Upd3FXj8sOVjzbH2sz//o9sU
jOYUhzLO1jeLIc6l0wnzRfE=
-----END RSA PRIVATE KEY-----
PRI;
// 公钥
$public = <<
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqMOqccKACBV1rGWN0DKF
JgeLgGJNHAETiE3gi0Tqc8EQ7XF0Qyd0z/y68IL4k5Zjw/1QLcWtNXlu/sZglAmO
yLmhvVJkQBe6vEV0Pk++HHvM0heiiFkW1r/gzqvOtMwpmmvc6+QwR4H+V5sAuv0q
gYUJRO1sa3nDTiQu0MeaNVfy4WeYQD+Z8YOs6aEr0zGYrYkEkVbnp6qLT7dIg/G+
E0XF+7IjRiBNpqO8aAp4ye1b94ri4upHM36R+VqAf5OeIWZ3GT3P8DeJuElmOH9b
qA69l7ZAgzQDg7obuyzM9WL5O8kbMl+zcKKZix84bY3Ujkj5ybM00FJDWvvAwksS
YQIDAQAB
-----END PUBLIC KEY-----
PUB;
// JAVA 生成的签名
// 验证
//$encrypt = 'flCNTyn6pydpBy7zPuJ6zaIpVMz47RdhmqsFsdRgHZF79H78R9Hhkw5sf3T86f6ESDSCD+3Fj/JSHZE9+hXyUt4i6NH41MKBVLr8pgZBpkwExPcBXa13vSa2dFniDbu2ZHiKRJGZWtGTmQPOHAxOqfnNxEv0StP8Hit8Plva/ug7tdGCi4j6sjhTWpB2vUFI2tzSnbeOQWJ+dfa6zrwbIC8EHBYltUiRmMry3H7YYNI+rt16HvS7TrbVWPi90ClMdj64CEahlS9TLpzErMUuJcyubs12QLUhHKL9IMvqNMa8SF8eztp3ZmWTtC1YxFfSHhQBUiLV/bA+iJ7CYROwIw==';
//$verify = openssl_verify($data, base64_decode($encrypt), $public, OPENSSL_ALGO_SHA256);
//var_dump($verify);
//die;
//
生成签名去JAVA验证
//$isOK = openssl_sign($data, $sign, $private, OPENSSL_ALGO_SHA256);
//if ($isOK) {
// echo base64_encode($sign);
//}
package com.company;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws Exception {
String origin = "二〇二〇年四月四日 01:43:37";
String encrypt = "flCNTyn6pydpBy7zPuJ6zaIpVMz47RdhmqsFsdRgHZF79H78R9Hhkw5sf3T86f6ESDSCD+3Fj/JSHZE9+hXyUt4i6NH41MKBVLr8pgZBpkwExPcBXa13vSa2dFniDbu2ZHiKRJGZWtGTmQPOHAxOqfnNxEv0StP8Hit8Plva/ug7tdGCi4j6sjhTWpB2vUFI2tzSnbeOQWJ+dfa6zrwbIC8EHBYltUiRmMry3H7YYNI+rt16HvS7TrbVWPi90ClMdj64CEahlS9TLpzErMUuJcyubs12QLUhHKL9IMvqNMa8SF8eztp3ZmWTtC1YxFfSHhQBUiLV/bA+iJ7CYROwIw==";
if (verify(getPublic(), origin, encrypt)) {
System.out.println("验证通过!");
}
//
// System.out.println(signSHA256RSA(origin, getPrivate()));
}
private static String signSHA256RSA(String input, String strPk) throws Exception {
byte[] b1 = Base64.getDecoder().decode(strPk);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
KeyFactory kf = KeyFactory.getInstance("RSA");
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(kf.generatePrivate(spec));
privateSignature.update(input.getBytes(StandardCharsets.UTF_8));
byte[] s = privateSignature.sign();
return Base64.getEncoder().encodeToString(s);
}
private static boolean verify(String publicKeyStr, String originStr, String encrypted) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
byte[] decode = Base64.getDecoder().decode(encrypted);
byte[] data = originStr.getBytes();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyStr));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
Signature sha256withRSA = Signature.getInstance("SHA256withRSA");
sha256withRSA.initVerify(publicKey);
sha256withRSA.update(data);
return sha256withRSA.verify(decode);
}
public static String getPrivate() {
return "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCow6pxwoAIFXWsZY3QMoUmB4uAYk0cAROITeCLROpzwRDtcXRDJ3TP/LrwgviTlmPD/VAtxa01eW7+xmCUCY7IuaG9UmRAF7q8RXQ+T74ce8zSF6KIWRbWv+DOq860zCmaa9zr5DBHgf5XmwC6/SqBhQlE7WxrecNOJC7Qx5o1V/LhZ5hAP5nxg6zpoSvTMZitiQSRVuenqotPt0iD8b4TRcX7siNGIE2mo7xoCnjJ7Vv3iuLi6kczfpH5WoB/k54hZncZPc/wN4m4SWY4f1uoDr2XtkCDNAODuhu7LMz1Yvk7yRsyX7NwopmLHzhtjdSOSPnJszTQUkNa+8DCSxJhAgMBAAECggEAbxJgUoDdfPSKvw0Tmcw2P8JFeRi5gU3gChyfRWn1GHwf5PZ/u1bzlZPTgUnhylj3jl1g8M8iYYhrmfj8RVJJDCjIn27jlh9IAnN/vycCi4KbWka97RkdY/djQQJoiCu60exduU80y0tuF0Bn6amH2Tiy0g+lBNNdzEcaHMTR5HrNPS7wRCnU0i3aIZbGSfFT6EHQES5FE2q3hTrySrv4cqR2Jnk+UJPYMyl7/cgc/X7K1cHCVpHmahhgxzXK2KBoOs2fmLcpHvlxu8roJm2OWxUDAoZFKtP5W6j0lbIl3afbOJFjpH1SLOP55lAMGAU65Ili68yVWWQuJi+h23dDcQKBgQDR4ZKK8AvsWHSHIcuh6/bBkKSXCLatZhqXE5sjaQy1syzXtLQ1JDYilDgorpvmqOfwClScF/eQLTYO+qM5zQEfZpMjciLiywAvRCRFKlUSOE4jivfsMZLsZ617QSUMrxXRKlUXNMOEDP/wE5p+LiaxORGWMuKJYavfabnmeEnH3QKBgQDN2SblEQok5+Q6kx5twrIJUhKeexLwtDHVybObO95iYMTCjbfxxA48w7jmJl1cPADqNINeDPOHNIl16RQ4UHH6MO32FVoHlei9AtVqKxCpBiJvl7T7vg0n8Zr3uCANVmexdsSnq6DbqTrXCPufo9vmfkScGjK3lmgAxqyJUkouVQKBgGteobBQQ1lCm0JySJFqfI7jpz/Y5lNo05uMHSaNXEIsCnnDaRlyj/s6pkwxn3Ht4NHNByHfpPduGaSqFgzA0p00xXsxraUmQs7rZj63/FNY2KiYNGLxrX8hPv+6APEvNNMPe/5mMMuCNwCjlrqMc6DgWB3lpDyx6dJebQr5aI1FAoGAJLrws8L8mmU+Vi1WKqOo/PzGEb1IPecJVWpuP+7I2akGsuhywBMJr1IFNhv2YLTcPO4t2qRY9/Ep7f4u+3VvQQNmEpjwvZXEN6W/yvfwOxi7IEpjot/gnRYBXt5d6cNXMVVN9dUsGMXzl9ckfvHQFSrGt0v9bMDLwgexVbd3QRkCgYEAzTVg+3hY9lt1cdrwklOsYfw3K33lq+Ip8RZ7WjeuO6W2Fuvh/MHEBxnwcPEZSKIhOpOV2VdYQo80uqinE4il4IQqhf2qFOshGHrOspDbJUgtuVH5JkmQDeh5yT5+Upd3FXj8sOVjzbH2sz//o9sUjOYUhzLO1jeLIc6l0wnzRfE=";
}
public static String getPublic() {
return "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqMOqccKACBV1rGWN0DKFJgeLgGJNHAETiE3gi0Tqc8EQ7XF0Qyd0z/y68IL4k5Zjw/1QLcWtNXlu/sZglAmOyLmhvVJkQBe6vEV0Pk++HHvM0heiiFkW1r/gzqvOtMwpmmvc6+QwR4H+V5sAuv0qgYUJRO1sa3nDTiQu0MeaNVfy4WeYQD+Z8YOs6aEr0zGYrYkEkVbnp6qLT7dIg/G+E0XF+7IjRiBNpqO8aAp4ye1b94ri4upHM36R+VqAf5OeIWZ3GT3P8DeJuElmOH9bqA69l7ZAgzQDg7obuyzM9WL5O8kbMl+zcKKZix84bY3Ujkj5ybM00FJDWvvAwksSYQIDAQAB";
}
}