use*_*509 14 java encryption der private-key
我在Base64中的String中有我的私钥和公钥,其中使用ANS1 DER进行编码.我尝试创建java的实例PrivateKey并PublicKey:
byte [] llave2 = DatatypeConverter.parseBase64Binary(key);
PKCS8Key pkcs8 = new PKCS8Key( llave2, password.toCharArray()); //line 2
llave2 = pkcs8.getDecryptedBytes(); //line 3
certificado = DatatypeConverter.parseBase64Binary(cer);
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(llave2);
PrivateKey privateKey = kf.generatePrivate(ks);
X509EncodedKeySpec x = new X509EncodedKeySpec(certificado);
PublicKey publicKey = kf.generatePublic(x);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误PublicKey publicKey = kf.generatePublic(x).
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(Unknown Source)
at vital.cancelaciones.GeneraXMLCancelacion.main(GeneraXMLCancelacion.java:118)
Caused by: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
at sun.security.x509.X509Key.decode(Unknown Source)
at sun.security.x509.X509Key.decode(Unknown Source)
at sun.security.rsa.RSAPublicKeyImpl.<init>(Unknown Source)
at sun.security.rsa.RSAKeyFactory.generatePublic(Unknown Source)
... 3 more
Run Code Online (Sandbox Code Playgroud)
我想我应该使用第2行和第3行中的私钥执行与公钥类似的操作.因为证书也是加密的.有什么建议?
Koh*_*ert 35
为了测试您的场景,我创建了一个RSA私钥openssl.
openssl genrsa -out private.pem 1024
Run Code Online (Sandbox Code Playgroud)
然后我将此密钥转换为PKCS#8 DER格式.
openssl pkcs8 -topk8 -inform PEM -in private.pem -outform DER -out private.der -nocrypt
Run Code Online (Sandbox Code Playgroud)
手册中openssl提到PKCS#8和DER都是格式,所以就我而言,会发生以下情况:
pkcs8告诉openssl我我想使用PKCS#8格式的私钥.-topk8告诉它我会指定用私钥-in是不是在PKCS#8(否则它会假设它是).-inform并-in指定我想将(PEM)私钥转换为PKCS#8(没有-topk8它会尝试将PKCS#8格式的密钥转换为标准密钥格式).-outform并-out告诉它我想要一个DER格式的键作为输出.-nocrypt 告诉它我不想加密密钥.然后,使用我的RSA密钥(标准格式),我创建了一个证书.
openssl req -new -x509 -keyform PEM -key private.pem -outform DER -out public.der
Run Code Online (Sandbox Code Playgroud)
证书包含与我的私钥对应的公钥.
在所有这些之后,我用Base64编写了私钥和证书.
base64 private.der > private.der.b64
base64 public.der > public.der.b64
Run Code Online (Sandbox Code Playgroud)
生成了以下文件.
private.pem # standard
private.der # pkcs8/DER
private.der.b64
public.der # x509/DER
public.der.b64
Run Code Online (Sandbox Code Playgroud)
public static void main(String[] args) throws IOException, GeneralSecurityException {
// get a handle on the base64 encoded key and certificate
File privateKeyFile = new File("private.der.b64");
File publicKeyFile = new File("public.der.b64");
// pull them into arrays
byte[] privateKeyBytes = toByteArray(privateKeyFile);
byte[] publicKeyBytes = toByteArray(publicKeyFile);
// decode them
privateKeyBytes = toDecodedBase64ByteArray(privateKeyBytes);
publicKeyBytes = toDecodedBase64ByteArray(publicKeyBytes);
// get the private key
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
// get the public key
CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
Certificate certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(publicKeyBytes));
PublicKey publicKey = certificate.getPublicKey();
}
private static byte[] toByteArray(File file) throws IOException {
// java 7's try-with-resources statement
try (FileInputStream in = new FileInputStream(file);
FileChannel channel = in.getChannel()) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
channel.transferTo(0, channel.size(), Channels.newChannel(out));
return out.toByteArray();
}
}
private static byte[] toDecodedBase64ByteArray(byte[] base64EncodedByteArray) {
return DatatypeConverter.parseBase64Binary(
new String(base64EncodedByteArray, Charset.forName("UTF-8")));
}
Run Code Online (Sandbox Code Playgroud)
主要问题是你有证书而不是公钥.证书包含公钥,但无法加载X509EncodedKeySpec(...),这就是CertificateFactory必须使用的原因.
(顺便说一下这里有一篇很棒的文章/教程openssl和Java加密用法.我从那里获得了部分信息.)
| 归档时间: |
|
| 查看次数: |
38494 次 |
| 最近记录: |