OpenSsl
生成DER
格式的私钥,长度为118字节。 (openssl ecparam -genkey -name secp256k1 and so on
)。
在android KeyPairGenerator
中初始化为:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "SC");
ECGenParameterSpec spec = new ECGenParameterSpec("secp256k1");
keyPairGenerator.initialize(spec, new SecureRandom());
return keyPairGenerator.generateKeyPair();
返回长度为144的私钥。但我需要118.差异在哪里? smh是否在Android实现中添加?我怎么能得到118键长?无法找到实现来搞清楚。
答案 0 :(得分:2)
找到了一种方法。 生成密钥对:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "SC");
ECGenParameterSpec spec = new ECGenParameterSpec("secp256k1");
keyPairGenerator.initialize(spec, new SecureRandom());
KeyPair kp = keyPairGenerator.generateKeyPair();
获取私钥字节数组:
byte[] privateK = kp.getPrivate();
然后将私钥转换为 PKCS1 :
byte[] privBytes = privateKey.getEncoded();
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privBytes);
ASN1Encodable encodable = pkInfo.parsePrivateKey();
ASN1Primitive primitive = encodable.toASN1Primitive();
byte[] privBytesEncoded = primitive.getEncoded();
答案 1 :(得分:0)
这是一个好消息/坏消息。好消息是你想要的字节是PrivateKey.getEncoded()
返回的字节的子序列。坏消息是我没有意识到要抓住他们的好方法。好吧,有一种简单的方法:你想要的字节总是在PrivateKey.getEncoded()
的末尾,所以如果你知道字节序列的长度是 n (例如在你的例子中为118)然后只取PrivateKey.getEncoded()
的最后 n 个字节。
稍微困难的方法是使用Spongycastle / Bouncycastle ASN1例程解析编码,如下面的代码段所示:
private static byte[] encodePrivateKey(PrivateKey privateKey) throws Exception{
ASN1InputStream asn1InputStream = new ASN1InputStream(privateKey.getEncoded());
ASN1Primitive asn1Primitive = asn1InputStream.readObject();
DLSequence seq = (DLSequence) asn1Primitive;
ASN1OctetString octetString = (ASN1OctetString) seq.getObjectAt(2);
return octetString.getOctets();
}
我提供这个作为一个例子,但我必须警告你这很脆弱:我没有做任何真正的努力来遵循PKCS#8规范,我只是用ASN.1结构来抓住我知道的字节需要。