Cryptography ECCPrivateKey的Java字节数组-InvalidKeySpecException:无法识别编码密钥规范

Cryptography ECCPrivateKey的Java字节数组-InvalidKeySpecException:无法识别编码密钥规范,cryptography,bouncycastle,private-key,elliptic-curve,java-security,Cryptography,Bouncycastle,Private Key,Elliptic Curve,Java Security,当我试图从字节数组生成ECC私钥时,我得到了下面提到的异常。我拥有C库micro-ecc/uECC.h的公钥/私钥和外签名输出。C使用secp192r1曲线。我试图用Java中C生成的密钥验证数据。如何将字节数组转换为私钥/公钥 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); byte[] kb = new byte[]{(byte)0x24, (byte)0xF4, (byte)0x

当我试图从字节数组生成ECC私钥时,我得到了下面提到的异常。我拥有C库micro-ecc/uECC.h的公钥/私钥和外签名输出。C使用secp192r1曲线。我试图用Java中C生成的密钥验证数据。如何将字节数组转换为私钥/公钥

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] kb = new byte[]{(byte)0x24, (byte)0xF4, (byte)0x36, (byte)0x16, (byte)0xD0, (byte)0x96, (byte)0x12, (byte)0x63, (byte)0x90, (byte)0x2E, (byte)0x51, (byte)0xF6, (byte)0x87, (byte)0x55, (byte)0xAB, (byte)0xCB, (byte)0x5D, (byte)0xAC, (byte)0x56, (byte)0x1A, (byte)0xA5, (byte)0xFA, (byte)0x55, (byte)0xDB};
X509EncodedKeySpec ks = new X509EncodedKeySpec(kb);
KeyFactory kf = java.security.KeyFactory.getInstance("ECDH", "BC");
org.bouncycastle.jce.interfaces.ECPrivateKey remotePublicKey = (org.bouncycastle.jce.interfaces.ECPrivateKey)kf.generatePublic(ks);

java.security.spec.InvalidKeySpecException: encoded key spec not recognised
at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
我也尝试过使用

KeyFactory.getInstance("ECDH", "BC"); 
但它在上面抛出了相同的异常

KeyFactory.getInstance("EC");
投掷

java.security.InvalidKeyException: invalid key format

X509EncodedKeySpec(key)
PKCS8EncodedKeySpec(key)
构造函数以编码格式获取私钥/公钥。可以通过以下方式转换未编码的密钥字节:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp192r1");

ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(new BigInteger(1, privateKeyBytes), spec); 

ECNamedCurveSpec params = new ECNamedCurveSpec("secp192r1", spec.getCurve(), spec.getG(), spec.getN());
java.security.spec.ECPoint w = new java.security.spec.ECPoint(new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 0, 24)), new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 24, 48)));
PublicKey publicKey = factory.generatePublic(new java.security.spec.ECPublicKeySpec(w, params));

你从哪里得到字节数组的?我在C库micro-ecc/uECC.h中有公钥/私钥和外签名输出。我试图在Java中验证它。C使用secp192r1,但我不知道在Java中加载公钥/私钥时是否需要提供它,以及如何进行。当我在Java中生成密钥对并创建副本时,它工作得很好。@就像您使用
KeyPairGenerator.getInstance(“EC”)在Java中正确生成
EC
密钥对一样
然后可以使用
KeyFactory
方法对其进行解析。那么您的
byte[]
键可能是错误的,或者具有某种特定的格式。还请注意,您的代码中有一个错误(与异常无关):
kf.generatePublic(ks)
无法强制转换为
ECPrivateKey
,因此将其更改为:
(org.bouncycastle.jce.interfaces.ECPublicKey)kf.generatePublic(ks)
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp192r1");

ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(new BigInteger(1, privateKeyBytes), spec); 

ECNamedCurveSpec params = new ECNamedCurveSpec("secp192r1", spec.getCurve(), spec.getG(), spec.getN());
java.security.spec.ECPoint w = new java.security.spec.ECPoint(new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 0, 24)), new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 24, 48)));
PublicKey publicKey = factory.generatePublic(new java.security.spec.ECPublicKeySpec(w, params));