抱歉我的英语不好,老实说我对此了解甚少,所以请耐心等待。
我正在开发一个java应用程序,它将签名的请求发送到服务器。
为此,我必须生成 PEM
格式的
PKCS#1 RSA密钥对以进行签名和验证。我尝试过使用OpenSSL v.1.0.1。但生成的公钥是
X.509 PEM
.
这是我用来生成密钥的 openssl 命令:
私钥:
openssl genrsa -out name_of_private_key.pem 1024
公钥
openssl rsa -in name_of_private_key.pem -pub out > name_of_public_key.pem
我也浏览过这个线程,我发现了一个开源 JAVA 库 BouncyCastle: 在 Java 中生成 PKCS#1 格式的 RSA 密钥
但它说 BouncyCastle 仅适用于 PKCS#1 padding 而不是 encoding。
如果没有其他选项可用,我最好寻找使用 JAVA 或任何第三方生成它的方法。
OpenSSL 1.1.1默认使用PKCS#1标准生成私钥并以PEM格式进行编码 如下
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
您可以将 PEM/PKCS#1 密钥转换为 PEM/PKCS#8 密钥 如下
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
OPENSSL始终使用X.509标准导出公钥并以PEM格式编码
如下
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
我使用这些脚本来生成 RSA 密钥对。
Powershell - CreateKeyPair.ps1
Set-Alias openssl "C:\Program Files\OpenSSL-Win64-1-1-1\bin\openssl.exe"
openssl version
Write-Host "=== GENERATE PRIVATE KEY --- Format: PKCS#1 --- File: private.txt==="
openssl genrsa -f4 -out private.txt 4096
Write-Host "=== GENERATE PRIVATE KEY --- Format: PKCS#8 --- File: private8.txt==="
openssl pkcs8 -topk8 -inform pem -in private.txt -outform PEM -nocrypt -out private8.txt
Write-Host "=== GENERATE PUBLIC KEY --- Format: X.509 --- File: public.txt==="
openssl rsa -in private.txt -outform PEM -pubout -out public.txt
CMD - CreateKeyPair.bat
@ECHO OFF
set openssl="C:\Program Files\OpenSSL-Win64-1-1-1\bin\openssl.exe"
%openssl% version
ECHO "=== GENERATE PRIVATE KEY --- Format: PKCS#1 --- File: private.txt==="
%openssl% genrsa -f4 -out private.txt 4096
ECHO "=== GENERATE PRIVATE KEY --- Format: PKCS#8 --- File: private8.txt==="
%openssl% pkcs8 -topk8 -inform pem -in private.txt -outform PEM -nocrypt -out private8.txt
ECHO "=== GENERATE PUBLIC KEY --- Format: X.509 --- File: public.txt==="
%openssl% rsa -in private.txt -outform PEM -pubout -out public.txt
在 OpenSSL3.0 中,命令 genrsa 已弃用,我们需要使用 genpkey。 OpenSSL 3.0默认使用PKCS#8标准生成私钥并以PEM格式编码
我使用这些脚本来生成 RSA 密钥对。
Powershell - CreateKeysOpenSSL3.0.ps1
Set-Alias openssl "C:\Program Files\OpenSSL-Win64\bin\openssl.exe"
openssl version
Write-Host "=== GENERATE PRIVATE KEY --- Format: PEM/PKCS#8 --- File: private.txt==="
openssl genpkey -out private.txt -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:4096
Write-Host "=== GENERATE PUBLIC KEY --- Format: PEM/X.509 --- File: public.txt==="
openssl pkey -inform PEM -outform PEM -in private.txt -pubout -out public.txt
CMD-CreateKeysOpenSSL3.0.bat
@ECHO OFF
set openssl="C:\Program Files\OpenSSL-Win64\bin\openssl.exe"
%openssl% version
ECHO "=== GENERATE PRIVATE KEY --- Format: PEM/PKCS#8 --- File: private.txt==="
%openssl% genpkey -out private.txt -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:4096
ECHO "=== GENERATE PUBLIC KEY --- Format: PEM/X.509 --- File: public.txt==="
%openssl% pkey -inform PEM -outform PEM -in private.txt -pubout -out public.txt
从 Java 生成 - 私有 PEM/PKCS#8 和公共 PEM/X.509
您可以在 https://replit.com/@JomaCorpFX/JavaPemRsaKeyPair#Main.java 中测试/运行此代码
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.util.Base64;
public class Main {
private static final String RsaPemPrivateKeyInitialString = "-----BEGIN PRIVATE KEY-----";
private static final String RsaPemPrivateKeyFinalString = "-----END PRIVATE KEY-----";
private static final String RsaPemPublicKeyInitialString = "-----BEGIN PUBLIC KEY-----";
private static final String RsaPemPublicKeyFinalString = "-----END PUBLIC KEY-----";
private static final int PEM_LINE_LEN = 64;
public static String InsertLineBreaks(String data, int lineBreaksLength)
{
StringBuilder sb = new StringBuilder();
int Segments = data.length() / lineBreaksLength;
if (Segments < 0)
{
return data;
}
else
{
for (int i = 0; i < Segments; i++)
{
sb.append(data.substring(i * lineBreaksLength, i*lineBreaksLength + lineBreaksLength));
sb.append(System.lineSeparator());
}
if (Segments * lineBreaksLength < data.length())
{
sb.append(data.substring(Segments * lineBreaksLength));
sb.append(System.lineSeparator());
}
return sb.toString().trim();
}
}
public static RsaKeyPair createKeyPair(int keySize) throws Exception {
RsaKeyPair result = new RsaKeyPair();
KeyPairGenerator MyKeyPairGenerator = KeyPairGenerator.getInstance("RSA");
MyKeyPairGenerator.initialize(keySize, new SecureRandom());
KeyPair MyKeyPair = MyKeyPairGenerator.generateKeyPair();
result.setPublicKey(RsaPemPublicKeyInitialString + System.lineSeparator() + InsertLineBreaks(Base64.getEncoder().encodeToString(MyKeyPair.getPublic().getEncoded()), PEM_LINE_LEN) + System.lineSeparator() + RsaPemPublicKeyFinalString);
result.setPrivateKey(RsaPemPrivateKeyInitialString + System.lineSeparator() + InsertLineBreaks(Base64.getEncoder().encodeToString(MyKeyPair.getPrivate().getEncoded()),PEM_LINE_LEN) + System.lineSeparator() + RsaPemPrivateKeyFinalString);
return result;
}
public static void main(String[] args) throws Exception {
RsaKeyPair keyPair = createKeyPair(4096);
System.out.println(keyPair.toString());
}
public static class RsaKeyPair
{
private String PublicKey;
private String PrivateKey;
public RsaKeyPair()
{
}
public RsaKeyPair(String PublicStringKey, String PrivateStringKey)
{
this.PublicKey = PublicStringKey;
this.PrivateKey = PrivateStringKey;
}
public String getPublicKey()
{
return PublicKey;
}
public void setPublicKey(String PublicStringKey)
{
this.PublicKey = PublicStringKey;
}
public String getPrivateKey()
{
return PrivateKey;
}
public void setPrivateKey(String PrivateStringKey)
{
this.PrivateKey = PrivateStringKey;
}
@Override
public String toString()
{
return String.format("Public\n%s\nPrivate\n%s", PublicKey, PrivateKey);
}
}
}
输出
Public
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz/hDwUW560ADH74ejSUh
CVfdkJyLX9MlqkIanMgsRnVGqzc2Mz9flpsphOJvDVsWJ2IMkDgZAKZ0foqKve+4
UuOLDjEIogIsNCU0w5Bkqct4YMsR24kGem6zm/40IG+yFtRWEb7DEzrYt6bJ6S24
KvWxFN0YmIAg1QLVYinB3qtXdbyzGBtn/rY+0Dir/C2nibuafcitmmOgY4rocXIr
BZlui+zUyoml8r8LcWScpwWcx35gqaxw7E5ayUOdGDViPJyFg0Hs5p6RtttWCA2W
YILVf/4NRJj5gp293PQECeHlBOSqBzJDIZfF7aWi3/qdClMxKL5RSFCqLaYeIh5p
Fl+L5y4lHWnsNipppaqZlTw+wHrl3eVSCmMlQXC9yRMedzIqejXWDl1QN+FSpcaQ
8pfyfhPzbT8v+DICff9K2IjQcA/4eew0qNcdd0FKYaFoViQ7nT91kS9E+vTf5v16
/KQlNX0ywNIHPcku7VMZ5a5/9oEJPGcL8hFExHIEtWwcJ+zcrk5srNEBp4xgWaKv
nIUfhJJfqZ3huCT0eRxbdq9yQ0qdRo0Rc1w/LnKs9OKH6D8WMyJs5qQwuk+vIjSx
MZWjVIt6r11vrE9ySwO/V4IjrQnb/KjflzkOqIhEbEjpnnwqreSxvwKhRvvBauFw
EEuL16QpSo54H5JDLgh4dyMCAwEAAQ==
-----END PUBLIC KEY-----
Private
-----BEGIN PRIVATE KEY-----
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
z3YIPsJ7PD4BGnEaBg0eMq72qTrD
-----END PRIVATE KEY-----
虽然 OpenSSL 库支持 PKCS#1 编码,但 OpenSSL 的命令行版本只会输出 x.509 格式的 RSA 公钥。不幸的是,您似乎别无选择,只能编写一些使用 OpenSSL 库以 PKCS#1 格式输出密钥的代码。
仅供参考,PKCS#1 密钥使用这些页眉/页脚:
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----
x.509 键使用这些页眉/页脚:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
您可以强制 OpenSSH 以旧的 PEM/PKCS#1 格式生成密钥:
ssh-keygen -t rsa -b 4096 -o -a 100 -f id_rsa -m PEM < /dev/null
总结一下其他答案的一些评论。这是您需要的完整魔法咒语:
openssl genrsa -traditional -out server.key 2048
openssl rsa -traditional -RSAPublicKey_out -in server.key -out public.key