gpt4 book ai didi

java - Java生成的数字签名不会在openssl中验证

转载 作者:行者123 更新时间:2023-12-02 01:23:54 27 4
gpt4 key购买 nike

我正在用 Java 签署一个二进制文件。我能够在 Java 代码中进行签名和验证,但是当在 openssl 中使用生成的签名时,它无法验证相同的二进制文件。步骤是:加载数据 -> 创建 SHA256 哈希 -> 签署哈希

这应该相当于在 openssl 中执行此操作:openssl dgst -sha256 -sign private.key -binary target.bin > 签名.bin核实:openssl dgst -sha256 -验证public.key -签名signature.bin

我验证了 sha256 与 openssl 生成的 sha256 相匹配。

public class Main {

public static void main(final String[] args) {
Signature signer;
KeyStore ks;
byte[] signature;
PrivateKey privateKey;
PublicKey publicKey;
String alias = "ctest3";
String sigfile = "c:\\temp\\signature";
String datafile = "c:\\temp\\data.bin";

try {
ks = KeyStore.getInstance("ncipher.sworld", "nCipherKM");
FileInputStream in = new FileInputStream("C:\\private\\ctest3.ncsw");
ks.load(in, null);
} catch (KeyStoreException |
NoSuchAlgorithmException |
CertificateException |
IOException |
NoSuchProviderException e) {
System.err.println(e.getMessage());
return;
}

try {
privateKey = (PrivateKey) ks.getKey(alias, null);
Certificate cert = ks.getCertificate(alias);
publicKey = cert.getPublicKey();
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}

byte[] payload;
try {
payload = Files.readAllBytes(Paths.get(datafile));
} catch (IOException e) {
System.out.println(e.getMessage());
return;
}

byte[] spayload = sha256(payload, false);
if (spayload == null) {
return;
}

try {
signer = Signature.getInstance("SHA256withECDSA");
signer.initSign(privateKey);
signer.update(spayload);
signature = signer.sign();
} catch (NoSuchAlgorithmException | SecurityException | SignatureException | InvalidKeyException e) {
System.out.println(e.getMessage());
return;
}

writeBytesToFile(signature, sigfile);
KeyPair kp = new KeyPair(publicKey, privateKey);

if (Verify(datafile, sigfile, kp)) {
System.out.println("success");
}
}

private static byte[] sha256(byte[] data) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
byte[] mDigest = digest.digest(data);
return mDigest;
} catch (NoSuchAlgorithmException e) {
return null;
}
}

private static boolean Verify(String filename, String signaturePath, KeyPair kp) {
Signature verify;
byte[] dataRaw;
byte[] signature;
byte[] data;

try {
dataRaw = Files.readAllBytes(Paths.get(filename));
signature = Files.readAllBytes(Paths.get(signaturePath));
} catch (IOException e) {
System.out.println(e.getMessage());
return false;
}

data = sha256(dataRaw, false);
if (data == null)
return false;

try {
verify = Signature.getInstance("SHA256withECDSA");
PublicKey pub = kp.getPublic();
verify.initVerify(pub);
verify.update(data);
if (verify.verify(signature))
return true;
} catch (NoSuchAlgorithmException | SecurityException | SignatureException | InvalidKeyException e) {
System.out.println(e.getMessage());
return false;
}

return false;
}

private static void writeBytesToFile(byte[] bFile, String fileDest) {
try (FileOutputStream fileOuputStream = new FileOutputStream(fileDest)) {
fileOuputStream.write(bFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}

最佳答案

事实证明,当使用 SHA256withECDSA key 启动 Signature 对象时,它会在sign() 调用期间自行生成 SHA256 哈希值。删除上述代码中对“sha256()”的调用可使用 OpenSSL 进行验证。

关于java - Java生成的数字签名不会在openssl中验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57598661/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com