How to serialize SEC1 encoded ECDSA public key to ASN.1 DER format with Rust?

I have written the Python version of the conversion method, but the Rust version I don't know how to write,

Rust cannot be written using the openssl package,

I query the data and it seems to be available k256="0.13.1" der = "0.7.5" replace

Currently known public keys are of Vec type I don't know how to convert the public key from SEC1 encoding to ASN.1 DER encoding

Below is part of the code I implemented

use der::{Encoder, Length};
use k256::elliptic_curve::sec1::{ToEncodedPoint, FromEncodedPoint};
use k256::{PublicKey, EncodedPoint};
use der::asn1::{BitString, ObjectIdentifier};

fn sec1_to_der(sec1_key: &[u8]) -> Result<Vec<u8>, der::Error> {
    // Load the SEC1-encoded ECDSA public key as the public key object
    let public_key = PublicKey::from_sec1_bytes(sec1_key).expect("error");

    // Define the OID for secp256k1 (1.3.132.0.10)
    let secp256k1_oid: ObjectIdentifier = k256::pkcs8::ObjectIdentifier::new("1.3.132.0.10");

    // TODO: How to serialize SEC1-encoded ECDSA to ASN.1 DER format here

}

fn main() {
    let der_encoded_public_key:Vec<u8> = vec![3, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217, 162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251, 246];;
    let der_key = sec1_to_der(&der_encoded_public_key);
    match der_key {
        Ok(der_key) => {
            println!("{:?}", der_key);
        }
        Err(e) => {
            println!("{:?}", e);
        }
    }
}

According to the PublicKey documentation, you can directly use the serde framework to get the result you want.

When the optional serde feature of this create is enabled, Serialize and Deserialize impls are provided for this type.

The serialization is binary-oriented and supports ASN.1 DER Subject Public Key Info (SPKI) as the encoding format.

So in Cargo.toml, you should add k256 = { version = "0.13.1", features = ["serde"] }

You can then use your serde serializer of choice to perform the conversion. For example, to get a hexadecimal string representation of the DER data, you can use serde_json:

// don't use unwrap() in production code
let der_hex: String = serde_json::to_string(&public_key).unwrap();
1 Like

The DER encoding for public keys is X.509 Subject Public Key Info, a.k.a. SPKI, and is implemented in the spki crate.

PublicKey impls the spki::EncodePublicKey trait.

EncodePublicKey::to_public_key_der can be used to obtain the DER serialization.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.