Android 密钥对生成
Android keypair generation
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();
returns 长度为 144 的私钥。但我需要118。有什么区别? android实现中是否添加了smh?我怎么能得到 118 键长度?找不到要弄清楚的实现。
这是个好消息 news/bad。好消息是您想要的字节是 PrivateKey.getEncoded()
返回的字节的子序列。坏消息是,据我所知,没有找到它们的好方法。好吧,有一个简单的方法:你想要的字节总是在 PrivateKey.getEncoded()
的末尾,所以如果你知道字节序列的长度是 n(例如 118 in你的例子)然后只取 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 结构来获取字节我知道需要。
找到了一种方法来做到这一点。
生成密钥对:
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();
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();
returns 长度为 144 的私钥。但我需要118。有什么区别? android实现中是否添加了smh?我怎么能得到 118 键长度?找不到要弄清楚的实现。
这是个好消息 news/bad。好消息是您想要的字节是 PrivateKey.getEncoded()
返回的字节的子序列。坏消息是,据我所知,没有找到它们的好方法。好吧,有一个简单的方法:你想要的字节总是在 PrivateKey.getEncoded()
的末尾,所以如果你知道字节序列的长度是 n(例如 118 in你的例子)然后只取 PrivateKey.getEncoded()
.
一种稍微困难的方法是使用 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 结构来获取字节我知道需要。
找到了一种方法来做到这一点。 生成密钥对:
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();