Help learning cryptography with Rust

#1

Hi,

As a novice in cryptography I was wondering how to start with it relying only on Rust. As a beginner, I am mostly interested into libraries supporting both symmetric and asymmetric cryptography solution. My current research led me to following conclusions (I would like your input on):

  1. Currently the best maintained library for crypto in Rust is ring library ( What is your opinion? )
  2. There are not to many examples on how to properly implement an encryption protocol. Let say I would like to use the one from rust-crypto, however, when you start digging a bit further into, it turns out there is no authentication utilized within it. Hm… bummer… Something I did not know it is important. I realize there is a lot to it but a starting point would be helpful (Any tips, materials, examples, cookbooks you might provide here? )
  3. I couldn’t find any examples how to utilize asymetric encryption with rust. Any suggestions ?
  4. I came across branca but I am not quite sure if it can be utilized to cipher a text. Any help in briefly describing what it is and what is used for would be much appreciated.

That is all for now…

Thnx

M

0 Likes

#2

What kind of protocol do you want to implement? You say you’re a cryptography novice, which likely means any protocol you design or implement will have critical security flaws. Can you just use an existing protocol such as TLS instead?

1 Like

#3

That is absolutely true ! My aim is purely educational I want to understand how a protocol works TLS/SSL and I understand it will be cr… with serious security issues. But I want to know how it works, so I’ll be writing examples, posting them here and looking for your input (plus I think this would be good for others as a learning material ) I’don’t know, maybe I’m just wasting time but let see… Any pointers / tips ?

UPDATE:

This is one of the examples I do not understand Why it does not work:

extern crate ring;

use ring::aead::*;
use ring::pbkdf2::*;
use ring::rand::SystemRandom;
use ring::rand::SecureRandom;
use std::num::NonZeroU32;
use ring::digest::*;

fn main() {
    // This password will be used to generate a key
    let password = b"nice password";

    // Usually the salt has some random data and something that relates to the user
    let salt = [0, 1, 2, 3, 4, 5, 6, 7];

    // Keys are sent as &[T] and must have 32 bytes
    let mut key = [0; 32];
    let dig = NonZeroU32::new(100).unwrap();
    derive(&SHA256, dig, &salt, &password[..], &mut key);

    // My private data
    let content = b"This is the text that needs to be encrypted and it holds the entire ASCII alphabet /%&$#".to_vec();
    println!("Content to encrypt's size {}", content.len());

    // Additional data that you would like to send and it would not be encrypted but it would be signed - what is this data ?
    let additional_data = b"";
	
    // Ring uses the same input variable as output
    let mut in_out = content.clone();

    // The input/output variable need some space for a suffix  - do they and why?
    println!("Tag len {}", CHACHA20_POLY1305.tag_len());
    for _ in 0..CHACHA20_POLY1305.tag_len() {
        in_out.push(0);
    }

    // Opening key used to decrypt data
    let opening_key = OpeningKey::new(&CHACHA20_POLY1305, &key).unwrap();

    // Sealing key used to encrypt data  - Why is this necessary?
    let sealing_key = SealingKey::new(&CHACHA20_POLY1305, &key).unwrap();


   let nonce = Nonce::try_assume_unique_for_key(&key).unwrap();
   let ad = Aad::from(additional_data);

	
    // Encrypt data into in_out variable
    let output_size = seal_in_place(&sealing_key, nonce, ad, &mut in_out,
                                    CHACHA20_POLY1305.tag_len()).unwrap();

    println!("Encrypted data's size {}", output_size);  // not working hm...
0 Likes

#4

If you look at the backtrace, you see that the failure is coming from this line:

   let nonce = Nonce::try_assume_unique_for_key(&key).unwrap();

You are trying to use the key as the nonce. This is not secure. Nonce means “number used once” and you must follow that direction. Each time you call seal_in_place you should generate a new random number of NONCE_LEN and pass that to Nonce::try_assume_unique_for_key (or assume_unique_for_key).

1 Like

#5

I’d recommend this book. It’s free, beginner friendly.

https://www.crypto101.io/

1 Like