win-crypto-ng

crates.io docs.rs MSRV Build status License

Safe Rust bindings to Microsoft Windows Cryptography API : Next Generation (CNG)

CNG are cryptographic primitives and utilities provided by the operating system and/or hardware. It is available since Windows Vista and replaces the now deprecated CryptoAPI.

The primitives do not depend on OpenSSL or other libraries of the sort, they are provided by Microsoft and/or by the hardware manufacturer. They are the primitives used in kernel space programs. Therefore, if you are using Microsoft Windows, you already accepted to trust these primitives.

CNG Features

Supported features in Rust

More to come

Examples

Asymmetric encryption (RSA)

```rust use wincryptong::asymmetric::{AsymmetricKey, EncryptionPadding, Rsa}; let key = AsymmetricKey::builder(Rsa).key_bits(1024).build().unwrap();

let plaintext = b"This is an important message.";

let padding = Some(EncryptionPadding::Pkcs1); let ciphertext = key.encrypt(padding.clone(), &*plaintext).unwrap(); asserteq!(ciphertext.len(), 1024 / 8); let decoded = key.decrypt(padding, ciphertext.asref()).unwrap(); asserteq!(plaintext, decoded.asref()); ```

Digital signatures

```rust use wincryptong::asymmetric::signature::{Signer, Verifier, SignaturePadding}; use wincryptong::asymmetric::{AsymmetricKey, Rsa}; use wincryptong::hash::HashAlgorithmId;

let key = AsymmetricKey::builder(Rsa).key_bits(1024).build().unwrap();

let data: Vec = (0..32).collect(); let padding = SignaturePadding::pkcs1(HashAlgorithmId::Sha256); let signature = key.sign(&*data, Some(padding)).expect("Signing to succeed");

key.verify(&data, &signature, Some(padding)).expect("Signature to be valid");

key.verify(&[0xDE, 0xAD], &signature, Some(padding)).expecterr("Bad digest"); key.verify(&data, &[0xDE, 0xAD], Some(padding)).expecterr("Bad signature"); ```

Symmetric encryption

```rust use wincryptong::symmetric::{ChainingMode, SymmetricAlgorithm, SymmetricAlgorithmId, Padding};

const KEY: &'static str = "0123456789ABCDEF"; const IV: &'static str = "asdfqwerasdfqwer"; const DATA: &'static str = "This is a test.";

let iv = IV.asbytes().tovec();

let algo = SymmetricAlgorithm::open(SymmetricAlgorithmId::Aes, ChainingMode::Cbc).unwrap(); let key = algo.newkey(KEY.asbytes()).unwrap(); let ciphertext = key.encrypt(Some(&mut iv.clone()), DATA.asbytes(), Some(Padding::Block)).unwrap(); let plaintext = key.decrypt(Some(&mut iv.clone()), ciphertext.asslice(), Some(Padding::Block)).unwrap();

asserteq!(std::str::fromutf8(&plaintext.as_slice()[..DATA.len()]).unwrap(), DATA); ```

Hash functions

```rust use wincryptong::hash::{HashAlgorithm, HashAlgorithmId};

const DATA: &'static str = "This is a test.";

let algo = HashAlgorithm::open(HashAlgorithmId::Sha256).unwrap(); let mut hash = algo.newhash().unwrap(); hash.hash(DATA.asbytes()).unwrap(); let result = hash.finish().unwrap();

asserteq!(result.asslice(), &[ 0xA8, 0xA2, 0xF6, 0xEB, 0xE2, 0x86, 0x69, 0x7C, 0x52, 0x7E, 0xB3, 0x5A, 0x58, 0xB5, 0x53, 0x95, 0x32, 0xE9, 0xB3, 0xAE, 0x3B, 0x64, 0xD4, 0xEB, 0x0A, 0x46, 0xFB, 0x65, 0x7B, 0x41, 0x56, 0x2C, ]); ```

Cryptographically secure random number generator

```rust use wincryptong::random::{RandomAlgorithmId, RandomNumberGenerator};

let mut buffer = [0u8; 32]; let rng = RandomNumberGenerator::systempreferred(); rng.genrandom(&mut buffer).unwrap();

assert_ne!(&buffer, &[0u8; 32]); ```

License

Licensed under the 3-Clause BSD License. See LICENSE.md for more details.

Copyright (c) 2019-2020 Émile Grégoire. All rights reserved.