Search code examples
javabouncycastlejce

Construct x509 encoded public key from algorithm oid and byte[] value of key


I have algorithm oid and byte array with public key value. I need to encode it as asn1 defined in the X.509 standard:

 SubjectPublicKeyInfo ::= SEQUENCE {
   algorithm AlgorithmIdentifier,
   subjectPublicKey BIT STRING }

How can I do this, except of manually constructing asn1 structure?

For example I have oid 1.2.643.7.1.1.1.1, public point value 7800A33627EF627D19C0A8E1C284067031851A9860A92E0B405B0561643FF1B6056A31FD01AD1D5E74213175D2F3808509C759418FD08554C20C88B109072207 and I want to represent it as

SEQUENCE {  
  OBJECT IDENTIFIER '1 2 643 7 1 1 1 1'   
  BIT STRING, encapsulates {
    OCTET STRING
   78 00 A3 36 27 EF 62 7D 19 C0 A8 E1 C2 84 06 70
   31 85 1A 98 60 A9 2E 0B 40 5B 05 61 64 3F F1 B6
   05 6A 31 FD 01 AD 1D 5E 74 21 31 75 D2 F3 80 85
   09 C7 59 41 8F D0 85 54 C2 0C 88 B1 09 07 22 07
  }
}

upd: Thanks to Wilx's answer! Final code for GOST 34.10-2012 with 256 bit key

    byte[] publicPoint = Hex.decode("7800A33627EF627D19C0A8E1C284067031851A9860A92E0B405B0561643FF1B6056A31FD01AD1D5E74213175D2F3808509C759418FD08554C20C88B109072207");

    GOST3410PublicKeyAlgParameters parameters = new GOST3410PublicKeyAlgParameters(
            RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA,
            RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256);

    SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo(
            new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, parameters),
            new DEROctetString(publicPoint));

    byte[] encoded = spki.getEncoded();

Solution

  • It all depends on what the OID identifies, IMHO. I am not entirely sure by the following. I had to look up the OID manually.

        byte[] data = Hex.decode("7800A33627EF627D19C0A8E1C284067031851A9860A92E0B405B0561643FF1B6056A31FD01AD1D5E74213175D2F3808509C759418FD08554C20C88B109072207");
        SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo(
            new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256),
            new DEROctetString(data));
        ASN1Primitive asn1 = spki.toASN1Primitive();
    

    I tried to use org.bouncycastle.jcajce.provider.asymmetric.ecgost12.BCECGOST3410_2012PublicKey#BCECGOST3410_2012PublicKey(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) but for some unknown to me reason it is not public but only package-private constructor.