feat: v0.2.0-dev, encrypt supports x25519
This commit is contained in:
@@ -10,7 +10,7 @@ use rsa::Pkcs1v15Encrypt;
|
||||
use rust_util::{debugging, failure, information, opt_result, simple_error, success, util_msg, warning, XResult};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::{util, util_ecdh};
|
||||
use crate::{util, util_ecdh, util_x25519};
|
||||
use crate::compress::GzStreamEncoder;
|
||||
use crate::config::{TinyEncryptConfig, TinyEncryptConfigEnvelop};
|
||||
use crate::crypto_aes::aes_gcm_encrypt;
|
||||
@@ -233,6 +233,9 @@ fn encrypt_envelops(key: &[u8], envelops: &[&TinyEncryptConfigEnvelop]) -> XResu
|
||||
TinyEncryptEnvelopType::Pgp => {
|
||||
encrypted_envelops.push(encrypt_envelop_pgp(key, envelop)?);
|
||||
}
|
||||
TinyEncryptEnvelopType::PgpX25519 => {
|
||||
encrypted_envelops.push(encrypt_envelop_ecdh_x25519(key, envelop)?);
|
||||
}
|
||||
TinyEncryptEnvelopType::Ecdh => {
|
||||
encrypted_envelops.push(encrypt_envelop_ecdh(key, envelop)?);
|
||||
}
|
||||
@@ -245,7 +248,22 @@ fn encrypt_envelops(key: &[u8], envelops: &[&TinyEncryptConfigEnvelop]) -> XResu
|
||||
fn encrypt_envelop_ecdh(key: &[u8], envelop: &TinyEncryptConfigEnvelop) -> XResult<TinyEncryptEnvelop> {
|
||||
let public_key_point_hex = &envelop.public_part;
|
||||
let (shared_secret, ephemeral_spki) = util_ecdh::compute_shared_secret(public_key_point_hex)?;
|
||||
let shared_key = util::simple_kdf(shared_secret.as_slice());
|
||||
|
||||
encrypt_envelop_shared_secret(key, &shared_secret, &ephemeral_spki, envelop)
|
||||
}
|
||||
|
||||
fn encrypt_envelop_ecdh_x25519(key: &[u8], envelop: &TinyEncryptConfigEnvelop) -> XResult<TinyEncryptEnvelop> {
|
||||
let public_key_point_hex = &envelop.public_part;
|
||||
let (shared_secret, ephemeral_spki) = util_x25519::compute_x25519_shared_secret(public_key_point_hex)?;
|
||||
|
||||
encrypt_envelop_shared_secret(key, &shared_secret, &ephemeral_spki, envelop)
|
||||
}
|
||||
|
||||
fn encrypt_envelop_shared_secret(key: &[u8],
|
||||
shared_secret: &[u8],
|
||||
ephemeral_spki: &[u8],
|
||||
envelop: &TinyEncryptConfigEnvelop) -> XResult<TinyEncryptEnvelop> {
|
||||
let shared_key = util::simple_kdf(shared_secret);
|
||||
let (_, nonce) = util::make_key256_and_nonce();
|
||||
|
||||
let encrypted_key = aes_gcm_encrypt(&shared_key, &nonce, key)?;
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::cmd_info::CmdInfo;
|
||||
|
||||
mod util;
|
||||
mod util_ecdh;
|
||||
mod util_x25519;
|
||||
mod compress;
|
||||
mod config;
|
||||
mod spec;
|
||||
|
||||
@@ -50,6 +50,8 @@ pub struct TinyEncryptEnvelop {
|
||||
pub enum TinyEncryptEnvelopType {
|
||||
#[serde(rename = "pgp")]
|
||||
Pgp,
|
||||
#[serde(rename = "pgp-x25519")]
|
||||
PgpX25519,
|
||||
#[serde(rename = "age")]
|
||||
Age,
|
||||
#[serde(rename = "ecdh")]
|
||||
@@ -65,6 +67,7 @@ impl TinyEncryptEnvelopType {
|
||||
pub fn get_name(&self) -> &'static str {
|
||||
match self {
|
||||
TinyEncryptEnvelopType::Pgp => "pgp",
|
||||
TinyEncryptEnvelopType::PgpX25519 => "pgp-x25519",
|
||||
TinyEncryptEnvelopType::Age => "age",
|
||||
TinyEncryptEnvelopType::Ecdh => "ecdh",
|
||||
TinyEncryptEnvelopType::Kms => "kms",
|
||||
|
||||
19
src/util_x25519.rs
Normal file
19
src/util_x25519.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use rand::rngs::OsRng;
|
||||
use rust_util::{opt_result, simple_error, XResult};
|
||||
use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
|
||||
pub fn compute_x25519_shared_secret(public_key_point_hex: &str) -> XResult<(Vec<u8>, Vec<u8>)> {
|
||||
let public_key_bytes = opt_result!(hex::decode(public_key_point_hex), "Parse X25519 public key hex failed: {}");
|
||||
if public_key_bytes.len() != 32 {
|
||||
return simple_error!("Parse X25519 key failed: not 32 bytes");
|
||||
}
|
||||
let public_key_bytes: [u8; 32] = public_key_bytes.try_into().unwrap();
|
||||
let public_key_card = PublicKey::from(public_key_bytes);
|
||||
|
||||
let ephemeral_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
let ephemeral_public = PublicKey::from(&ephemeral_secret);
|
||||
|
||||
let shared_secret = ephemeral_secret.diffie_hellman(&public_key_card);
|
||||
|
||||
Ok((shared_secret.as_bytes().to_vec(), ephemeral_public.as_bytes().to_vec()))
|
||||
}
|
||||
Reference in New Issue
Block a user