本篇博客提供有关ECC的DER文件的Java解析方式,如ECC公钥和ECC签名值对应DER文件的解析,PEM文件也能够使用本博客中提供的解析方式进行解析,PEM文件只是DER文件经过Base64编码之后,加上了头尾说明信息的一类文件而已。

import org.bouncycastle.asn1.*;
import java.io.ByteArrayInputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.ECGenParameterSpec;
public class DecodeDERECCPubKey {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
byte[] derByte = getECCPubKey();
ASN1Primitive asn1 = toAsn1Primitive(derByte);
if(asn1 instanceof ASN1Sequence)
{
ASN1Sequence asn1Sequence = (ASN1Sequence) asn1;
ASN1Encodable[] asn1Encodables = asn1Sequence.toArray();
for (ASN1Encodable asn1Encodable : asn1Encodables) {
ASN1Primitive asn1Primitive = asn1Encodable.toASN1Primitive();
if(asn1Primitive instanceof DLSequence)
{
DLSequence asn1DLSequence = (DLSequence) asn1Primitive;
ASN1Encodable[] asn1DLEncodables = asn1DLSequence.toArray();
for(ASN1Encodable asn1DLEncodable : asn1DLEncodables)
{
if(asn1DLEncodable instanceof ASN1ObjectIdentifier)
{
ASN1ObjectIdentifier asn1ObjectIdentifier = (ASN1ObjectIdentifier) asn1DLEncodable;
System.out.println(asn1ObjectIdentifier.toString());
}
}
}
else if(asn1Primitive instanceof DERBitString)
{
DERBitString derBitString = (DERBitString) asn1Primitive;
System.out.println(derBitString.toString());
}
}
}
}
private static ASN1Primitive toAsn1Primitive(byte[] data) throws Exception
{
try (ByteArrayInputStream inStream = new ByteArrayInputStream(data);
ASN1InputStream asnInputStream = new ASN1InputStream(inStream);)
{
return asnInputStream.readObject();
}
}
private static byte[] getECCPubKey() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA");
ECGenParameterSpec ecParameterSpec = new ECGenParameterSpec("P-256");
keyPairGenerator.initialize(ecParameterSpec);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair.getPublic().getEncoded();
}
}

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.Signature;
import java.security.spec.ECGenParameterSpec;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class DecodeEcdsaSignature {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
byte[] signature = getSignature();
ASN1Primitive asn1 = toAsn1Primitive(signature);
if (asn1 instanceof ASN1Sequence) {
ASN1Sequence asn1Sequence = (ASN1Sequence) asn1;
ASN1Encodable[] asn1Encodables = asn1Sequence.toArray();
for (ASN1Encodable asn1Encodable : asn1Encodables) {
ASN1Primitive asn1Primitive = asn1Encodable.toASN1Primitive();
if (asn1Primitive instanceof ASN1Integer) {
ASN1Integer asn1Integer = (ASN1Integer) asn1Primitive;
BigInteger integer = asn1Integer.getValue();
System.out.println(integer.toString());
}
}
}
}
private static ASN1Primitive toAsn1Primitive(byte[] data) throws Exception
{
try (ByteArrayInputStream inStream = new ByteArrayInputStream(data);
ASN1InputStream asnInputStream = new ASN1InputStream(inStream);)
{
return asnInputStream.readObject();
}
}
private static byte[] getSignature() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA");
ECGenParameterSpec ecParameterSpec = new ECGenParameterSpec("P-256");
keyPairGenerator.initialize(ecParameterSpec);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(keyPair.getPrivate());
signature.update("message to sign".getBytes("UTF-8"));
return signature.sign();
}
}
有关DER文件的解析核心在于找到对应文件的数据结构层次信息。