tuupola / branca-spec

Authenticated and encrypted API tokens using modern crypto
223 stars 7 forks source link

Rust implementation #6

Closed tuupola closed 5 years ago

tuupola commented 6 years ago

Rust implementation would be welcome. Something similar as frank_jwt by @GildedHonour. Anyone interested in implementing it write me a note here and I will add it to the docs.

GildedHonour commented 6 years ago

I'll look into and if I decide to implement it I'll notify you here.

tuupola commented 6 years ago

Sounds great! Let me know.

is2ei commented 5 years ago

Hi, It looks the status is still "help wanted", right? I'd like to work on that. 😄

tuupola commented 5 years ago

Excellent! Let me know when you have something ready and I will add a link.

is2ei commented 5 years ago

It seems @return has been working on this task without mentioning it... 😅 https://crates.io/crates/branca

tuupola commented 5 years ago

Is the code somewhere in GitHub? I cannot find it.

@is2ei You could still of course do your own version of it (if you are interested).

is2ei commented 5 years ago

Thanks for your comment!

Is the code somewhere in GitHub? I cannot find it.

No, I guess he just occupied the name branca in crates.io (modules portal like npmjs.com) and he does not put the reposiotry in public. I consider to send him PRs instead of creating my own repo since he owns the name branca in crates.io .

return commented 5 years ago

@tuupola @is2ei I too was also interested in a Rust implementation for some time. I just open-sourced a WIP implementation using sodiumoxide for now and it seems to be able to generate branca tokens well.

https://github.com/return/branca

I also tested it with the test vectors and the implementation seem to be passing them.

tuupola commented 5 years ago

Looks good! I will add the link.

tuupola commented 5 years ago

@return Since I do not write Rust, could you also provide example usage I could add to the website? Same as other languages but with Rust of course.

https://branca.io/

return commented 5 years ago

@tuupola Sure, below is a small example of using the Rust implementation similar to the Branca examples on the website:

This part goes in the Cargo.toml.

[dependencies]
branca = "^0.5.0"
serde_json = "^1.0"
serde_derive = "1.0.83"
ring = "0.13.5"
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate branca;
extern crate ring;

use branca::{encode, decode};
use ring::rand::{SystemRandom, SecureRandom};

#[derive(Serialize, Deserialize, Debug)]
struct User {
    user: String,
    scope: Vec<String>,
}

fn main(){

    let message = json!({
        "user" : "someone@example.com",
        "scope":["read", "write", "delete"],
    }).to_string();

    // Generate Nonce (24 bytes in length)
    let rand_nonce = SystemRandom::new();
    let mut nonce = vec![0; 24];
    rand_nonce.fill(nonce.as_mut()).unwrap();

    // Encode Message
    let key = b"supersecretkeyyoushouldnotcommit";
    let timestamp = 123206400;
    let branca_token = encode(message.as_str(), key.to_vec(), nonce, timestamp).unwrap();

    // Decode Message
    let payload = decode(branca_token.as_str(), key.to_vec(), 0).unwrap();
    let json: User = serde_json::from_str(payload.as_str()).unwrap();

    println!("{}", branca_token);
    println!("{}", payload);
    println!("{:?}", json);
}
return commented 5 years ago

@tuupola Any update on including this Rust example on the homepage?

tuupola commented 5 years ago

Have not forgotten it. Try to do it today or tomorrow.

BTW. Is it possible to use the Rust version without passing the nonce and timestamp manually? The other examples are without manually passed nonce and timestamp.

tuupola commented 5 years ago

Added the above example to https://branca.io

return commented 5 years ago

@tuupola I've released a new version of my implementation and I've simplified creating a branca token without passing in the other fields like this:

#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate branca;

use branca::{encode, decode};

#[derive(Serialize, Deserialize, Debug)]
struct User {
    user: String,
    scope: Vec<String>,
}

fn main(){
    let message = json!({
        "user" : "someone@example.com",
        "scope":["read", "write", "delete"],
    }).to_string();

    let key = b"supersecretkeyyoushouldnotcommit".to_vec();
    let token = Branca::new(&key).unwrap();

    // Encode Message
    let branca_token = token.encode(message.as_str()).unwrap();

    // Decode Message
    let payload = token.decode(branca_token.as_str(), 0).unwrap();

    let json: User = serde_json::from_str(payload.as_str()).unwrap();

    println!("{}", branca_token);
    println!("{}", payload);
    println!("{:?}", json);
}
tuupola commented 5 years ago

Thanks, updated!

https://branca.io/