Create certificates

For more formats, see Rust Crypto Formats.

  • der
  • pem-rfc7468
  • pkcs8
  • x509-cert

DER

der-website der der-crates.io der-github der-lib.rs cat-cryptography cat-data-structures cat-encoding cat-parser-implementations cat-no-std

Pure Rust embedded-friendly implementation of the Distinguished Encoding Rules (DER) for Abstract Syntax Notation One (ASN.1) as described in ITU X.690 with full support for heapless no_std targets.

use der::Decode;
use der::Encode;
use der::Sequence;

// This example demonstrates how to encode a struct to DER format, and decode it
// back using the `der` crate.

// Define a struct to be encoded/decoded
// Note that we derive the `Sequence` trait.
#[derive(Debug, PartialEq, Sequence)]
struct MyStruct {
    field1: u32,
    field2: String,
}
fn main() {
    // Create an instance of MyStruct
    let my_struct = MyStruct {
        field1: 42,
        field2: "Hello, DER!".to_string(),
    };

    // Encode the struct to DER
    let der_encoded = my_struct.to_der().expect("Failed to encode");
    println!("DER Encoded: {:?}", der_encoded);

    // Decode the DER back to MyStruct
    let decoded_struct =
        MyStruct::from_der(&der_encoded).expect("Failed to decode");
    println!("Decoded Struct: {:?}", decoded_struct);

    // Verify that the decoded struct matches the original
    assert_eq!(my_struct, decoded_struct);
}

pem-rfc7468

pem-rfc7468-website pem-rfc7468 pem-rfc7468-crates.io pem-rfc7468-github pem-rfc7468-lib.rs cat-cryptography cat-data-structures cat-encoding cat-parser-implementations cat-no-std

PEM Encoding (RFC 7468) for PKIX, PKCS, and CMS Structures, implementing a strict subset of the original Privacy-Enhanced Mail encoding intended specifically for use with cryptographic keys, certificates, and other messages. Provides a no_std-friendly, constant-time implementation suitable for use with cryptographic private keys.

// use pem_rfc7468::LineEnding;
// use pem_rfc7468::decode_vec;
// use pem_rfc7468::encode_string;

// fn main() -> Result<(), Box<dyn std::error::Error>> {
//     // Example DER-encoded data (replace with your actual data)
//     let der_data = vec![
//         0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48,
// 0x86,         0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x20, 0x41,
// 0x20, 0x42,         0x20, 0x43, 0x20, 0x20, 0x48,
//     ];

//     // Encode DER data to PEM
//     let type_label = "MY_DATA";
//     let pem_encoded =
//         encode_string(type_label, LineEnding::default(), &der_data)?;
//     // Specifies the line ending for PEM encoding (default is \r\n).

//     println!("PEM-encoded data:\n{}", pem_encoded);

//     // Decode PEM data back to DER
//     let (decoded_type_label, decoded_data) =
//         decode_vec(pem_encoded.as_bytes())?;

//     assert_eq!(type_label, decoded_type_label);
//     assert_eq!(der_data, decoded_data);

//     println!("Successfully decoded PEM data.");

//     Ok(())
// }

pkcs8

pkcs8-website pkcs8 pkcs8-crates.io pkcs8-github pkcs8-lib.rs cat-cryptography cat-data-structures cat-encoding cat-parser-implementations cat-no-std

Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification (RFC 5208), with additional support for PKCS#8v2 asymmetric key packages (RFC 5958).

use std::fs::File;
use std::io::Write;

use base64ct::LineEnding;
// Trait to parse a private key from a PKCS#8 encoded document.
use pkcs8::DecodePrivateKey;
// Trait to serialize a private key to a PKCS#8 encoded document.
use pkcs8::EncodePrivateKey;
// Operating System's Random Number Generator
use rand::rngs::OsRng;
use rsa::RsaPrivateKey;
// Components of an RSA private key
use rsa::traits::PrivateKeyParts;

// Encoding and decoding private keys in PKCS#8 format.
// PKCS #8 is a standard syntax for storing private key information.
// PKCS #8 private keys are typically exchanged in the PEM base64-encoded file
// format PEM is a method of encoding binary data as a string (also known as
// ASCII armor). It contains a header and a footer line (specifying the type of
// data that is encoded and showing begin/end if the data is chained together)
// and the data in the middle is the base 64 data.
fn main() -> anyhow::Result<()> {
    // Generate an RSA keypair
    let mut rng = OsRng;
    let private_key = RsaPrivateKey::new(&mut rng, 2048)?;

    // Encode the private key in PKCS#8 format
    let pkcs8_pem = private_key.to_pkcs8_pem(LineEnding::LF)?;

    // Save the PKCS#8 key to a file
    let mut file = File::create("private_key.pem")?;
    file.write_all(pkcs8_pem.as_bytes())?;
    file.flush()?;

    // Read the PKCS#8 key from the file
    let pem: String = std::fs::read_to_string("private_key.pem")?;

    // Decode the private key from PKCS#8
    let decoded_private_key = RsaPrivateKey::from_pkcs8_pem(&pem)?;

    // Verify that the decoded key is the same as the original
    assert_eq!(private_key.primes(), decoded_private_key.primes());

    println!("Successfully read and decoded PKCS#8 private key.");

    Ok(())
}

x509-cert

x509-cert-website x509-cert x509-cert-crates.io x509-cert-github x509-cert-lib.rs cat-cryptography cat-data-structures cat-encoding cat-no-std

Pure Rust implementation of the X.509 Public Key Infrastructure Certificate format as described in RFC 5280.

// use std::fs::File;
// use std::io::BufReader;

// use chrono::Utc;
// use rustls::internal::pemfile::certs;
// use rustls::internal::pemfile::rsa_private_keys;
// use x509_cert::builder::CertificateBuilder;
// use x509_cert::builder::Profile;
// use x509_cert::name::Name;
// use x509_cert::serial_number::SerialNumber;
// use x509_cert::time::Duration;
// use x509_cert::time::Time;

// fn main() -> anyhow::Result<()> {
//     // Load existing certificate and private key (replace with your actual
//     // paths)
//     let cert_file = File::open("path/to/your/cert.pem")?;
//     let key_file = File::open("path/to/your/key.pem")?;
//     let cert_reader = BufReader::new(cert_file);
//     let key_reader = BufReader::new(key_file);

//     let certs = certs(&mut cert_reader).unwrap();
//     let keys = rsa_private_keys(&mut key_reader).unwrap();

//     // Create a new certificate builder
//     let now = Utc::now();
//     let not_before = Time::from(now);
//     let not_after = Time::from(now + Duration::days(365)); // Valid for one
// year     let serial_number = SerialNumber::random();
//     let subject = Name::build_common_name("example.com").unwrap();
//     let issuer = subject.clone();

//     let mut builder = CertificateBuilder::new(
//         Profile::Server,
//         serial_number,
//         Validity {
//             not_before,
//             not_after,
//         },
//         issuer,
//         subject,
//     )?;

//     // Add extensions (optional)
//     // ...

//     // Sign the certificate
//     let certificate = builder.sign(&keys[0])?;

//     // Print or save the certificate (DER encoding)
//     println!("Certificate: {:?}", certificate.to_der()?);

//     Ok(())
// }