我爱编程

Java 读取private Key

2018-03-27  本文已影响0人  kamiSDY

最近,用Fabric JAVA SDK做enroll动作的时候,在读取private Key的时候出现了一个错误:

org.bouncycastle.openssl.PEMException: problem parsing PRIVATE KEY: java.lang.IllegalArgumentException: wrong version for private key info
    at org.bouncycastle.openssl.PEMParser$PrivateKeyParser.parseObject(Unknown Source)
    at org.bouncycastle.openssl.PEMParser.readObject(Unknown Source)
    at main.SampleUser.getPrivateKeyFromBytes(SampleUser.java:163)
    at main.SampleUser$1.getKey(SampleUser.java:86)
    at org.hyperledger.fabric.sdk.User.userContextCheck(User.java:94)
    at org.hyperledger.fabric.sdk.HFClient.setUserContext(HFClient.java:257)
    at main.carDemo.main(carDemo.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:282)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: wrong version for private key info
    at org.bouncycastle.asn1.pkcs.PrivateKeyInfo.<init>(Unknown Source)
    at org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(Unknown Source)
    ... 13 more

查看Openssl 版本

使用openssl verison或者openssl version -a查看。

OpenSSL 1.0.1e-fips 11 Feb 2013
built on: Mon Feb 20 14:38:48 UTC 2017
platform: linux-x86_64
options:  bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx) 
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/etc/pki/tls"
engines:  rdrand dynamic 

定位问题

用线上生产环境的key测了下,没出现问题。初步判断,本地生成key的方式不同导致的。
在Stack Overflow上找了找。发现了一个回答,总结下:

这里,我们有两种方法:

这里有一个RSA文件转化的实例。EC算法可以参考这个改一下。

自己实现PEMParser

当然,我们可以自己实现PEMParser的功能,前提是我们已经获得了PEM的数据。这里有个例子:

import java.security.*;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
...
static void SO48996981BCparseECprivate () throws Exception {
    byte[] server_sec1 = DatatypeConverter.parseBase64Binary("MHgCAQEEIA27nM1klj9pVxOzJrO4aBLFvXTtOJnf+vMhiv3HA+3noAsGCSskAwMCCAEBB6FEA0IABG1erLtLyTbC5yN8gVY4a0JPO5eefKftWMbSQij2Ks5TaNNuj/tqigFqsk1g/l2UBBkIx2KdpeiY8nVddwMpzho=");
    ASN1Sequence seq = ASN1Sequence.getInstance(server_sec1);
    org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq);
    AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters());
    byte[] server_pkcs8 = new PrivateKeyInfo(algId, pKey).getEncoded();
    KeyFactory fact = KeyFactory.getInstance ("EC","BC");
    PrivateKey pkey = fact.generatePrivate (new PKCS8EncodedKeySpec(server_pkcs8));
    // for test only:
    System.out.println (pkey.getClass().getName() + " " + pkey.getAlgorithm());
}

最后,其实我们并不需要java来做这件事情,OpenSSL完全提供了ECDH(其他算法也ok?)的agreement/derivation。所以,可以直接使用OpenSSL脚本来执行。

上一篇 下一篇

猜你喜欢

热点阅读