Is there any pure rust code to decrypt an AES CCM data?

Hello,

I have a encrypted text using sjcl. I used the demo 2 to encrypt a piece of text using the following parameters:

password: "password"
salt: 3B889F6A 5CE3FC4B
key: 7DED638F DD30ACDB 4A34D153 48F12D95 BB388A7E 8CB9C35B 8D9C9009 89454E1E
iv: ECCFB278 E13D4DA6 695BBD75 77C61F7C
message: "Hallo Welt!"

gaining this output:

{
    "iv":"7M+yeOE9TaZpW711d8YffA==",
    "v":1,
    "iter":1000,
    "ks":256,
    "ts":64,
    "mode":"ccm",
    "adata":"",
    "cipher":"aes",
    "salt":"O4ifalzj/Es=",
    "ct":"Lsbc3V06Fruulq83CRSiD2dohA=="
}

I found a similar post,but it use C++ code to do this.

Is there any pure rust code to decrypt it?
Thank you.

You can use serde_json to parse the JSON, base64 to decode the Base64 strings, and aes/ccm to perform the actual decryption.

/*
[dependencies]
aes = "0.8.2"
base64 = "0.21.0"
ccm = "0.5.0"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"
*/

use aes::Aes256;
use base64::{engine::general_purpose::STANDARD, Engine};
use ccm::{
    aead::{generic_array::typenum::Unsigned, Aead},
    consts::{U11, U12, U13, U8},
    Ccm, KeyInit,
};
use serde::Deserialize;
use std::str;

fn decrypt(input: &str, key: &str) -> Vec<u8> {
    #[derive(Deserialize)]
    struct Input {
        iv: String,
        ct: String,
    }

    let input: Input = serde_json::from_str(input).unwrap();
    let iv = STANDARD.decode(input.iv).unwrap();
    let ct = STANDARD.decode(input.ct).unwrap();
    let key: Vec<u8> = key
        .split(" ")
        .flat_map(|chunk| u32::from_str_radix(chunk, 16).unwrap().to_be_bytes())
        .collect();

    fn decrypt_with<Alg: KeyInit + Aead>(key: &[u8], iv: &[u8], ct: &[u8]) -> Vec<u8> {
        Alg::new_from_slice(key)
            .unwrap()
            .decrypt(iv[..Alg::NonceSize::USIZE].try_into().unwrap(), &ct[..])
            .unwrap()
    }

    // SJCL automatically adjusts the nonce size, we must do so manually
    if ct.len() < 0x1_0008 {
        decrypt_with::<Ccm<Aes256, U8, U13>>(&key, &iv, &ct)
    } else if ct.len() < 0x100_0008 {
        decrypt_with::<Ccm<Aes256, U8, U12>>(&key, &iv, &ct)
    } else {
        decrypt_with::<Ccm<Aes256, U8, U11>>(&key, &iv, &ct)
    }
}

fn main() {
    let input = r#"{
        "iv":"7M+yeOE9TaZpW711d8YffA==",
        "v":1,
        "iter":1000,
        "ks":256,
        "ts":64,
        "mode":"ccm",
        "adata":"",
        "cipher":"aes",
        "salt":"O4ifalzj/Es=",
        "ct":"Lsbc3V06Fruulq83CRSiD2dohA=="
    }"#;
    let key = "7DED638F DD30ACDB 4A34D153 48F12D95 BB388A7E 8CB9C35B 8D9C9009 89454E1E";
    let output = decrypt(input, key);
    println!("{:?}", str::from_utf8(&output).unwrap());
}
2 Likes

It works,thank you very much

I found a crate called sjcl-rust to encrypt and decrypt earsier

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.