增加aes加解密

This commit is contained in:
zhl 2023-05-09 18:36:14 +08:00
parent 5150df13ed
commit 851a6ecf5b
8 changed files with 189 additions and 88 deletions

2
Cargo.lock generated
View File

@ -722,6 +722,7 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
name = "rustwallet" name = "rustwallet"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"aes-gcm",
"anyhow", "anyhow",
"argon2", "argon2",
"base64 0.21.0", "base64 0.21.0",
@ -729,6 +730,7 @@ dependencies = [
"ecies", "ecies",
"hex", "hex",
"primitive-types", "primitive-types",
"rand 0.8.5",
"scrypt", "scrypt",
"secp256k1", "secp256k1",
"serde", "serde",

View File

@ -27,3 +27,5 @@ ecies = {version = "0.2", default-features = false, features = ["pure"]}
base64 = "0.21.0" base64 = "0.21.0"
scrypt = { version = "0.11.0", default-features = false, features = ["simple"] } scrypt = { version = "0.11.0", default-features = false, features = ["simple"] }
argon2 = { version = "0.5.0" } argon2 = { version = "0.5.0" }
aes-gcm = "0.10.1"
rand = "0.8.5"

View File

@ -5,9 +5,9 @@
// //
use rustwallet::{ use rustwallet::{
free_cwallet, generate_sec_key, get_address, get_public_key, hash_pass_svr, hex_deflate, aes_decrypt, aes_encrypt, free_cwallet, generate_sec_key, get_address, get_public_key,
hex_inflate, keccak256_hash, new_wallet, rencrypt, sign, sign_for_tran, wallet_decrypt, hash_pass_svr, hex_deflate, hex_inflate, keccak256_hash, new_wallet, rencrypt, sign,
wallet_encrypt, CWallet, sign_for_tran, wallet_decrypt, wallet_encrypt, CWallet,
}; };
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::os::raw::c_char; use std::os::raw::c_char;
@ -147,5 +147,11 @@ fn main() {
let pass = "111111"; let pass = "111111";
let hash_pass = hash_pass_svr(str_to_cchar!(pass)); let hash_pass = hash_pass_svr(str_to_cchar!(pass));
print_cchar!(hash_pass); print_cchar!(hash_pass);
let str_encrypt = aes_encrypt(str_to_cchar!(pass));
print_cchar!(str_encrypt);
let str_plain = aes_decrypt(str_encrypt);
print_cchar!(str_plain);
} }
} }

View File

@ -11,7 +11,7 @@ use std::str::FromStr;
mod wallet; mod wallet;
use secp256k1::PublicKey; use secp256k1::PublicKey;
use wallet::wallet_impl::zencrypt; use wallet::wallet_impl::{zdecrypt, zencrypt};
use wallet_impl::Wallet; use wallet_impl::Wallet;
use crate::wallet::*; use crate::wallet::*;
@ -224,7 +224,8 @@ pub unsafe extern "C" fn wallet_decrypt(
) -> *mut c_char { ) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key); let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let msg_str = cchar_to_str!(msg); let msg_str = cchar_to_str!(msg);
let msg_decrypt = match rwallet.zdecrypt(msg_str) { let sk = rwallet.get_secret_key();
let msg_decrypt = match zdecrypt(sk, msg_str) {
Ok(v) => v, Ok(v) => v,
Err(err) => panic!("error decrypt: {:?}", err), Err(err) => panic!("error decrypt: {:?}", err),
}; };
@ -248,13 +249,35 @@ pub unsafe extern "C" fn hex_inflate(content: *const c_char) -> *mut c_char {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn hash_pass_svr(content: *const c_char) -> *mut c_char { pub unsafe extern "C" fn hash_pass_svr(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content); let content_str = cchar_to_str!(content);
let msg_hex = utils::pass_utils::hash_pass_svr(&content_str); let msg_hex = utils::crypto_utils::hash_pass_svr(&content_str);
str_to_cchar!(msg_hex)
}
#[no_mangle]
pub unsafe extern "C" fn hash_pass_client(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let msg_hex = utils::crypto_utils::hash_pass_client(&content_str);
str_to_cchar!(msg_hex) str_to_cchar!(msg_hex)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn keccak256_hash(content: *const c_char) -> *mut c_char { pub unsafe extern "C" fn keccak256_hash(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content); let content_str = cchar_to_str!(content);
let msg_hex = utils::pass_utils::keccak256_hash(&content_str); let msg_hex = utils::crypto_utils::keccak256_hash(&content_str);
str_to_cchar!(msg_hex)
}
#[no_mangle]
pub unsafe extern "C" fn aes_encrypt(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let pass = "2a3a6e3ef5e6e4617a09d91014cb54dcdc0dd6dcb1809d3f5701779651e51cf2";
let msg_hex = utils::crypto_utils::aes_encrypt(&content_str, &pass);
str_to_cchar!(msg_hex)
}
#[no_mangle]
pub unsafe extern "C" fn aes_decrypt(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let pass = "2a3a6e3ef5e6e4617a09d91014cb54dcdc0dd6dcb1809d3f5701779651e51cf2";
let msg_hex = utils::crypto_utils::aes_decrypt(&content_str, &pass);
str_to_cchar!(msg_hex) str_to_cchar!(msg_hex)
} }

121
src/utils/crypto_utils.rs Normal file
View File

@ -0,0 +1,121 @@
use aes_gcm::{
aead::{generic_array::GenericArray, Aead, KeyInit},
Aes256Gcm,
Nonce, // Or `Aes128Gcm`
};
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Argon2,
};
use base64::{engine::general_purpose, Engine as _};
use rand::prelude::*;
use std::str;
use tiny_keccak::keccak256;
pub fn hash_password(pass: &str) -> String {
let salt: SaltString = SaltString::generate(&mut OsRng);
let password = pass.as_bytes();
let password_hash: String = match Argon2::default().hash_password(password, &salt) {
Ok(v) => v.to_string(),
Err(e) => panic!("error hash password: {}", e),
};
general_purpose::STANDARD_NO_PAD.encode(&password_hash)
}
pub fn verify_password(pass: &str, password_hash: &str) -> bool {
let str_tmp = match general_purpose::STANDARD_NO_PAD.decode(password_hash) {
Ok(v) => v,
Err(e) => panic!("error decode base64 str: {}", e),
};
let s = match str::from_utf8(&str_tmp) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
let parsed_hash = match PasswordHash::new(&s) {
Ok(v) => v,
Err(e) => panic!("error parse password hash: {}", e),
};
let password = pass.as_bytes();
Argon2::default()
.verify_password(password, &parsed_hash)
.is_ok()
}
pub fn keccak256_hash(str: &str) -> String {
let data = str.as_bytes();
let hasher = keccak256(data);
hex::encode(&hasher)
}
pub fn hash_pass_client(str: &str) -> String {
let message = str.as_bytes();
let mut eth_message = format!("\x22cebg password pre hash:\n{}", message.len()).into_bytes();
eth_message.extend_from_slice(message);
let hasher = keccak256(&eth_message);
hex::encode(&hasher)
}
pub fn hash_pass_svr(str: &str) -> String {
let message = str.as_bytes();
let mut eth_message = format!("\x23cebg email regist:\n{}", message.len()).into_bytes();
eth_message.extend_from_slice(message);
let hasher = keccak256(&eth_message);
hex::encode(&hasher)
}
//
// This function is used to encrypt a string using AES-256-GCM algorithm
pub fn aes_encrypt(str: &str, key: &str) -> String {
// Convert the input string to bytes
let str_data = str.as_bytes();
// Decode the input key from hex to bytes and create a GenericArray object
let key = hex::decode(&key).expect("Invalid hex string");
let key = GenericArray::from_slice(&key);
// Create an AES-256-GCM cipher with the specified key
let cipher = Aes256Gcm::new(&key);
// Generate a random nonce of 96 bits (12 bytes)
let mut nonce_data = [0u8; 12];
thread_rng().fill_bytes(&mut nonce_data);
let nonce = GenericArray::from_slice(&nonce_data);
// Encrypt the data using the cipher and nonce
let ciphertext = match cipher.encrypt(nonce, str_data) {
Ok(v) => v,
Err(e) => panic!("error encrypt: {}", e),
};
// Encode the ciphertext and nonce as base64 strings
let cipher_str = general_purpose::STANDARD_NO_PAD.encode(&ciphertext);
let nonce_str = general_purpose::STANDARD_NO_PAD.encode(&nonce_data);
// Concatenate the encoded ciphertext and nonce with a period separator and return the result
nonce_str + cipher_str.as_str()
}
pub fn aes_decrypt(str: &str, key: &str) -> String {
let str_data = match general_purpose::STANDARD_NO_PAD.decode(str) {
Ok(v) => v,
Err(e) => panic!("error decode base64 str: {}", e),
};
if str_data.len() < 12 {
panic!("error decrypt: invalid data");
}
let v = 12;
let nonce_data = &str_data[..v];
let cipher_data = &str_data[v..];
let nonce = GenericArray::from_slice(&nonce_data);
let key = hex::decode(&key).expect("Invalid hex string");
let key = GenericArray::from_slice(&key);
let cipher = Aes256Gcm::new(&key);
let plaintext = match cipher.decrypt(nonce, cipher_data) {
Ok(v) => v,
Err(e) => panic!("error decrypt: {}", e),
};
let plaintext = str::from_utf8(&plaintext).expect("err convert to utf8");
plaintext.to_string()
}

View File

@ -1,2 +1,2 @@
pub mod pass_utils; pub mod crypto_utils;
pub mod str_utils; pub mod str_utils;

View File

@ -1,52 +0,0 @@
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Argon2,
};
use base64::{engine::general_purpose, Engine as _};
use std::str;
use tiny_keccak::keccak256;
pub fn hash_password(pass: &str) -> String {
let salt: SaltString = SaltString::generate(&mut OsRng);
let password = pass.as_bytes();
let password_hash: String = match Argon2::default().hash_password(password, &salt) {
Ok(v) => v.to_string(),
Err(e) => panic!("error hash password: {}", e),
};
general_purpose::STANDARD_NO_PAD.encode(&password_hash)
}
pub fn verify_password(pass: &str, password_hash: &str) -> bool {
let str_tmp = match general_purpose::STANDARD_NO_PAD.decode(password_hash) {
Ok(v) => v,
Err(e) => panic!("error decode base64 str: {}", e),
};
let s = match str::from_utf8(&str_tmp) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
let parsed_hash = match PasswordHash::new(&s) {
Ok(v) => v,
Err(e) => panic!("error parse password hash: {}", e),
};
let password = pass.as_bytes();
Argon2::default()
.verify_password(password, &parsed_hash)
.is_ok()
}
pub fn keccak256_hash(str: &str) -> String {
let data = str.as_bytes();
let hasher = keccak256(data);
hex::encode(&hasher)
}
pub fn hash_pass_svr(str: &str) -> String {
let message = str.as_bytes();
let mut eth_message = format!("\x23cebg email regist:\n{}", message.len()).into_bytes();
eth_message.extend_from_slice(message);
let hasher = keccak256(&eth_message);
hex::encode(&hasher)
}

View File

@ -32,6 +32,32 @@ pub fn zencrypt(pk: PublicKey, msg: &str) -> Result<String> {
Ok(str_encrypt) Ok(str_encrypt)
} }
pub fn zdecrypt(sk: SecretKey, msg1: &str) -> Result<String> {
let sk = sk.secret_bytes();
let mut msg: String = msg1.clone().to_string();
if msg.len() % 2 == 1 {
msg = "0".to_owned() + &msg;
}
println!("msg to decrypt: {:?}", &msg);
let msg = match hex::decode(&msg) {
Ok(v) => v,
Err(e) => panic!("error decode hex str: {}", e),
};
let msg_decrypt = match decrypt(&sk, &msg) {
Ok(v) => v,
Err(e) => panic!("error decrypt content: {}", e),
};
// println!("msg after decrypt: {:?}", &msg_decrypt);
// let msg_decrypt = hex::encode(msg_decrypt);
let str_decrypt = match str::from_utf8(&msg_decrypt) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
let result = str_decrypt.to_string();
Ok(result)
}
pub fn public_key_address(public_key: &PublicKey) -> H160 { pub fn public_key_address(public_key: &PublicKey) -> H160 {
let public_key = public_key.serialize_uncompressed(); let public_key = public_key.serialize_uncompressed();
debug_assert_eq!(public_key[0], 0x04); debug_assert_eq!(public_key[0], 0x04);
@ -119,7 +145,7 @@ impl Wallet {
} }
} }
fn get_secret_key(&self) -> SecretKey { pub fn get_secret_key(&self) -> SecretKey {
let key_str_0: &str = &self.master_key; let key_str_0: &str = &self.master_key;
let key0 = BigInt::parse_bytes(&key_str_0.as_bytes(), 16).unwrap(); let key0 = BigInt::parse_bytes(&key_str_0.as_bytes(), 16).unwrap();
let kp0: (usize, BigInt) = (1, key0); let kp0: (usize, BigInt) = (1, key0);
@ -197,31 +223,4 @@ impl Wallet {
let recid = _recovery_id.to_i32(); let recid = _recovery_id.to_i32();
Ok((s, recid)) Ok((s, recid))
} }
pub fn zdecrypt(&self, msg1: &str) -> Result<String> {
let sk = self.get_secret_key();
let sk = sk.secret_bytes();
let mut msg: String = msg1.clone().to_string();
if msg.len() % 2 == 1 {
msg = "0".to_owned() + &msg;
}
println!("msg to decrypt: {:?}", &msg);
let msg = match hex::decode(&msg) {
Ok(v) => v,
Err(e) => panic!("error decode hex str: {}", e),
};
let msg_decrypt = match decrypt(&sk, &msg) {
Ok(v) => v,
Err(e) => panic!("error decrypt content: {}", e),
};
// println!("msg after decrypt: {:?}", &msg_decrypt);
// let msg_decrypt = hex::encode(msg_decrypt);
let str_decrypt = match str::from_utf8(&msg_decrypt) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
let result = str_decrypt.to_string();
Ok(result)
}
} }