mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-04-20 13:39:15 +00:00

* Add some experiment code for crypto crate * feat: add crypto crate with ssl, rsa, ed25519 for https, encryption, signing * Implement aes encryption helper in crypto crate * ci: add dep for CI rust test (protobuf) * fix: try to fix window CI with next * fix: CI * ci: add dep for ubuntu * ci: fix * fix: openssl lib path in CI * fix: CI * update applications-rs, disable some tests * fix: CI * feat: add file transfer grpc proto and server setup * CI: try to fix CI * fix: missing proto in build.rs * ci: add cargo build before cargo test * fix: grpc file descriptor * ci: fix CI by removing a redundant main.rs * fix: disable local windows test in applications-rs which fails CI * ci: run CI rust test only on ubuntu, windows is failing. will be handled in another PR * fix: vue template * fix: allow unused variable * fix: remove node:buffer type from api shell.ts to avoid frontend build error * try to fix test in create-kunkun * upgrade api to 0.0.44, remove node:buffer * upgrade next template to 15 * feat: turn the default server into a https server * feat: make SSL certificate loadable from env * feat: add conditional SSL cert in debug mode, use local default cert, in production generate new self-signed cert every time app starts * chore: add vscode debug config * feat: add server public key * feat: setup sqlite db encryption * fix: settings hotkey * chore: add .gitkeep * ci: add node-fetch to dep for api package
93 lines
3.2 KiB
Rust
93 lines
3.2 KiB
Rust
//! ed25519 is a cryptographic signature algorithm.
|
|
//! It cannot be used for encryption, only for signing and verifying.
|
|
//!
|
|
//! For example, ed25519 is commonly used as SSH key.
|
|
//! When ssh login starts, the private key is used to sign a challenge message.
|
|
//! The server verifies the signature of the public key.
|
|
|
|
use openssl::{
|
|
pkey::{PKey, Private, Public},
|
|
sign::{Signer, Verifier},
|
|
};
|
|
|
|
use crate::types::Signature;
|
|
|
|
pub struct Ed25519Crypto {}
|
|
|
|
impl Ed25519Crypto {
|
|
pub fn generate_key() -> anyhow::Result<PKey<Private>> {
|
|
PKey::generate_ed25519().map_err(anyhow::Error::from)
|
|
}
|
|
|
|
pub fn generate_key_pair_pem() -> anyhow::Result<(Vec<u8>, Vec<u8>)> {
|
|
let private_key = PKey::generate_ed25519()?;
|
|
let private_pem = private_key.private_key_to_pem_pkcs8()?;
|
|
let public_pem = private_key.public_key_to_pem()?;
|
|
Ok((private_pem, public_pem))
|
|
}
|
|
|
|
pub fn private_key_from_pem(pem: &[u8]) -> anyhow::Result<PKey<Private>> {
|
|
PKey::private_key_from_pem(pem).map_err(anyhow::Error::from)
|
|
}
|
|
|
|
pub fn public_key_from_pem(pem: &[u8]) -> anyhow::Result<PKey<Public>> {
|
|
PKey::public_key_from_pem(pem).map_err(anyhow::Error::from)
|
|
}
|
|
|
|
pub fn sign(private_key: &PKey<Private>, message: &[u8]) -> anyhow::Result<Vec<u8>> {
|
|
let mut signer = Signer::new_without_digest(&private_key)?;
|
|
Ok(signer.sign_oneshot_to_vec(message)?)
|
|
}
|
|
|
|
pub fn verify(
|
|
public_key: &PKey<Public>,
|
|
message: &[u8],
|
|
signature: &[u8],
|
|
) -> anyhow::Result<bool> {
|
|
let mut verifier = Verifier::new_without_digest(public_key)?;
|
|
Ok(verifier.verify_oneshot(&signature, message)?)
|
|
}
|
|
}
|
|
|
|
impl Signature for Ed25519Crypto {
|
|
fn sign_with_pem(private_pem: &[u8], message: &[u8]) -> anyhow::Result<Vec<u8>> {
|
|
let private_key = Ed25519Crypto::private_key_from_pem(private_pem)?;
|
|
Ed25519Crypto::sign(&private_key, message)
|
|
}
|
|
|
|
fn verify_with_pem(
|
|
public_pem: &[u8],
|
|
message: &[u8],
|
|
signature: &[u8],
|
|
) -> anyhow::Result<bool> {
|
|
let public_key = Ed25519Crypto::public_key_from_pem(public_pem)?;
|
|
Ed25519Crypto::verify(&public_key, message, signature)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_ed25519_sign_verify() {
|
|
let (private_pem, public_pem) = Ed25519Crypto::generate_key_pair_pem().unwrap();
|
|
let message = b"hello world";
|
|
let private_key = Ed25519Crypto::private_key_from_pem(&private_pem).unwrap();
|
|
let public_key = Ed25519Crypto::public_key_from_pem(&public_pem).unwrap();
|
|
let signature = Ed25519Crypto::sign(&private_key, message).unwrap();
|
|
let verified = Ed25519Crypto::verify(&public_key, message, &signature).unwrap();
|
|
assert!(verified);
|
|
assert!(!Ed25519Crypto::verify(&public_key, b"hello world2", &signature).unwrap());
|
|
}
|
|
|
|
#[test]
|
|
fn test_ed25519_sign_verify_with_pem() {
|
|
let (private_pem, public_pem) = Ed25519Crypto::generate_key_pair_pem().unwrap();
|
|
let message = b"hello world";
|
|
let signature = Ed25519Crypto::sign_with_pem(&private_pem, message).unwrap();
|
|
let verified = Ed25519Crypto::verify_with_pem(&public_pem, message, &signature).unwrap();
|
|
assert!(verified);
|
|
}
|
|
}
|