Create certificates
For more formats, see Rust Crypto Formats.
DER
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 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
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
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(()) // }