gpt4 book ai didi

java - 使用 PEM 编码的加密私钥对消息进行本地签名

转载 作者:搜寻专家 更新时间:2023-10-30 19:53:54 25 4
gpt4 key购买 nike

我正在尝试使用 PEM(X.509) 证书(存储在磁盘上的 privateKey.pem 文件中)对通过 Java 中的套接字发送的消息进行签名,但我很难找到一个接近的示例。我通常是一名 C++ 专家,刚刚介入帮助完成这个项目,所以当我不熟悉 API 时,将它们全部组合成可以运行的代码对我来说有点困难。

不幸的是,我仅限于使用 Java (1.6.0 Update 16) 的标准方法,所以尽管我使用 BouncyCastle 找到了一个类似的示例的 PEMReader ,它对这个特定项目没有多大帮助。

我的 privateKey.pem key 受密码保护,形式为:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED DEK-Info:
DES-EDE3-CBC,63A862F284B1280B
[...]
tsjQI4H8lhOBuk+NelHu7h2+uqbBQzwkPoA8IqbPXUz+B/MAGhoTGl4AKPjfm9gu
OqEorRU2vGiSaUPgDaRhdPKK0stxMxbByUi8xQ2156d/Ipk2IPLSEZDXONrB/4O5
[...]
-----END RSA PRIVATE KEY-----

它们的 key 是使用 OpenSSL 生成的:

openssl.exe genrsa -out private_key.pem 4096

我无法在运行前将此 key 转换为 DER 或其他格式,任何必要的转换都需要在代码内部完成,因为 key 需要易于替换并且格式将保持 PEM。

我听说过很多我不太确定的事情,希望 SO 的集体思想可以帮助把这些碎片拼凑在一起。



听说PEM证书需要Base64 Decoded转换成DER证书才能使用。我有一个名为 MiGBase64 的 Base64 解码工具但我不完全确定这种解码需要如何/何时完成。


我已经迷失在 Java API 文档中,试图追踪存在的 15 种不同类型的 key 、KeyStores、KeyGenerators、证书等,但我对它们中的任何一个都不熟悉正确识别我需要使用哪些,以及如何一起使用它们。


基本算法看起来很简单,这就是为什么我一直无法编写同样简单的实现特别令人沮丧的原因:

1) 从文件中读取privateKey.pem
2) 将私钥加载到XXX类中,使用Passphrase解密 key
3) 使用带有签名类的 key 对象对消息进行签名



非常感谢帮助解决这个问题,尤其是示例代码。我一直在努力为这个问题寻找有用的例子,因为大多数“接近”的例子都是生成新的 key ,使用 BouncyCaSTLe,或者只是使用此处不适用的不同形式的 key /类。

这似乎是一个非常简单的问题,但它让我发疯,任何非常简单的答案?

最佳答案

如果您使用的是 BouncyCaSTLe,请尝试以下操作:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyPair;
import java.security.Security;
import java.security.Signature;
import java.util.Arrays;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;
import org.bouncycastle.util.encoders.Hex;

public class SignatureExample {

public static void main(String [] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());

String message = "hello world";
File privateKey = new File("private.pem");
KeyPair keyPair = readKeyPair(privateKey, "password".toCharArray());

Signature signature = Signature.getInstance("SHA256WithRSAEncryption");
signature.initSign(keyPair.getPrivate());
signature.update(message.getBytes());
byte [] signatureBytes = signature.sign();
System.out.println(new String(Hex.encode(signatureBytes)));

Signature verifier = Signature.getInstance("SHA256WithRSAEncryption");
verifier.initVerify(keyPair.getPublic());
verifier.update(message.getBytes());
if (verifier.verify(signatureBytes)) {
System.out.println("Signature is valid");
} else {
System.out.println("Signature is invalid");
}
}

private static KeyPair readKeyPair(File privateKey, char [] keyPassword) throws IOException {
FileReader fileReader = new FileReader(privateKey);
PEMReader r = new PEMReader(fileReader, new DefaultPasswordFinder(keyPassword));
try {
return (KeyPair) r.readObject();
} catch (IOException ex) {
throw new IOException("The private key could not be decrypted", ex);
} finally {
r.close();
fileReader.close();
}
}

private static class DefaultPasswordFinder implements PasswordFinder {

private final char [] password;

private DefaultPasswordFinder(char [] password) {
this.password = password;
}

@Override
public char[] getPassword() {
return Arrays.copyOf(password, password.length);
}
}
}

关于java - 使用 PEM 编码的加密私钥对消息进行本地签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1580012/

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