gpt4 book ai didi

java - 要转换为 PrivateKey 对象的字节

转载 作者:行者123 更新时间:2023-11-30 03:21:12 24 4
gpt4 key购买 nike

我的 JKS(Java key 存储)文件中有一个对称 key ,我想用对称 key 包装我的私钥。

我再次使用wrappedBytes作为PrivateKey对象。最后我想要 KeyPair 对象。

下面的代码给出了以下错误消息:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=125, too big.**

public KeyPair wrapPrivateKeyWithSymmetricKey(KeyPair keyPair) {

try {
PrivateKey priv = keyPair.getPrivate();
SecretKey symmetricKey = "bjksabfkasdbgvkasbvkkj";//symmetricKey from jks file

//wrapping Private Key
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.WRAP_MODE, symmetricKey);
byte[] wrappedKey = cipher.wrap(priv);

//wrappedKey bytes to PrivateKey Object
KeyFactory keyFactory = KeyFactory.getInstance(priv.getAlgorithm());
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(wrappedKey);
PrivateKey privateKey2 = keyFactory.generatePrivate(privateKeySpec); //above Error Throwing in this line

return new KeyPair(keyPair.getPublic(), privateKey2);;
}

我该如何解决这个问题?

最佳答案

在您的示例中,wrappedBytes 不在 PKCS #8 中格式。它只是一些 AES 加密 block (本质上是随机数据),没有编码结构。

如果您想创建一个加密 PKCS #8(正式名称为 EncryptedPrivateKeyInfo ),您将需要一个可以处理该问题的库。您尝试使用的内置 API 仅处理其明文有效负载 PrivateKeyInfo (如 its documentation 中所述)。

包装器没有太多内容,您可以自己编写必要的 DER 编码,或者使用像 BouncyCastle. 这样的库。

<小时/>

这里是使用 BouncyCaSTLe 编码和解码 EncryptyedPrivateKeyInfo 结构的代码。由于对 key 加密算法标识符及其参数的处理不当,JCE 提供的无用类不起作用。

import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;

final class PKCS8
{

private static final ASN1ObjectIdentifier AES = ASN1ObjectIdentifier.getInstance(NISTObjectIdentifiers.id_aes128_CBC);

static RSAPublicKey toPublic(RSAPrivateCrtKey pvt)
throws GeneralSecurityException
{
RSAPublicKeySpec pub = new RSAPublicKeySpec(pvt.getModulus(), pvt.getPublicExponent());
KeyFactory f = KeyFactory.getInstance("RSA");
return (RSAPublicKey) f.generatePublic(pub);
}

static byte[] encrypt(SecretKey secret, PrivateKey pvt)
throws Exception
{
Cipher enc = Cipher.getInstance("AES/CBC/PKCS5Padding");
enc.init(Cipher.WRAP_MODE, secret);
ASN1Encodable params = new DEROctetString(enc.getIV());
AlgorithmIdentifier algId = new AlgorithmIdentifier(AES, params);
byte[] ciphertext = enc.wrap(pvt);
return new EncryptedPrivateKeyInfo(algId, ciphertext).getEncoded();
}

static PrivateKey decrypt(SecretKey secret, byte[] pkcs8)
throws Exception
{
EncryptedPrivateKeyInfo info = new PKCS8EncryptedPrivateKeyInfo(pkcs8).toASN1Structure();
AlgorithmIdentifier id = info.getEncryptionAlgorithm();
byte[] iv = ((ASN1OctetString) id.getParameters()).getOctets();
Cipher dec = Cipher.getInstance("AES/CBC/PKCS5Padding");
dec.init(Cipher.UNWRAP_MODE, secret, new IvParameterSpec(iv));
return (PrivateKey) dec.unwrap(info.getEncryptedData(), "RSA", Cipher.PRIVATE_KEY);
}

}

关于java - 要转换为 PrivateKey 对象的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31298620/

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