第二十八 密钥

现代密码学的一个基本原则是“一切秘密寓于密钥之中”。

密钥分为两种:对称密钥与非对称密钥

  • 对称密码算法使用相同的密钥;
  • 公钥密码使用不同的密钥来对消息进行加密解密;
  • MAC消息认证码使用相同的密钥;
  • 数字签名使用不同的密钥来对消息进行签名和验证。

 密钥的管理

  • 如何生成公私钥对?
  • 如何根据编码后的公私钥对得到 PrivateKey, PublicKey ?
  • 如何保护私钥的安全?
  • 如何传输交换密钥?
  • 密钥共享

如何生成公私钥对?

RSA生成公私钥对
use rand_core::CryptoRngCore;

    use rsa::pkcs8::{self, DecodePublicKey, EncodePrivateKey, EncodePublicKey, LineEnding};

    use rsa::{Pkcs1v15Encrypt, PublicKey, RsaPrivateKey, RsaPublicKey};


    let mut rng = random::thread_rng();

    let bits = 2048;

    let priv_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");

    let pub_key = RsaPublicKey::from(&priv_key);

ECC生成公私钥对
#[test]

fn ecc() {

    use base64ct::LineEnding;

    use elliptic_curve::SecretKey;

    use p256::NistP256;

    use rand_core::OsRng; // requires 'getrandom' feature


    // 1. 生成私钥

    let key: SecretKey<NistP256> = SecretKey::random(&mut OsRng);

    let pem_str = key.to_sec1_pem(LineEnding::LF);

    println!("{:?}", pem_str);

    // 根据私钥生成公钥

    println!("{:?}", key.public_key());


    //2. 根据PEM格式字符串恢复私钥

    let private_key : Result<SecretKey<NistP256>, elliptic_curve::Error> = elliptic_curve::SecretKey::from_sec1_pem("-----BEGIN EC PRIVATE KEY-----\nMGsCAQEEIKUhSRir8XkO1BcqcgdgFxtapjz0UFyzwQQpcCJ6IZhcoUQDQgAEWsVX\ns/5B/A4rWT4hRk6EBP/tzRzQjJKZIoh9WQbV4eots1mPwiio6XYhcYD+zauInLNq\nK1i6dCgXjJ0GB1FEhA==\n-----END EC PRIVATE KEY-----");


    //3. 根据私钥生成公钥

    let public_key = private_key.unwrap().public_key();

    println!("{:?}", public_key);

}

SM2生成公私钥对
use libsm::sm2::signature::{SigCtx, Signature};


    let ctx = SigCtx::new();

    let (pk, sk) = ctx.new_keypair().unwrap();
(1)获得openssl支持椭圆曲线算法列表

        命令:openssl ecparam -list_curves

(2)生成SM2私钥文件

          命令:openssl ecparam -outform pem -out sm2PrivateKey.pem -name SM2 -genkey

(3)查看私钥文件

          命令:openssl ec -in sm2PrivateKey.pem -text

(4)生成SM2 公钥文件

          命令:openssl ec -in sm2PrivateKey.pem -pubout -out sm2PublicKey.pem

如何根据编码后的公私钥对得到 PrivateKey, PublicKey ?

    let private_key_pem = std::fs::read_to_string("private_key.pem").unwrap();

    let public_key_pem = std::fs::read_to_string("public_key.pem").unwrap();


    let priv_key = RsaPrivateKey::from_pkcs8_pem(&private_key_pem).unwrap();

    let pub_key = RsaPublicKey::from_public_key_pem(&public_key_pem).unwrap();

密钥交换

use k256::{EncodedPoint, PublicKey, ecdh::EphemeralSecret};

use rand_core::OsRng; // requires 'getrandom' feature


// Alice

let alice_secret = EphemeralSecret::random(&mut OsRng);

let alice_pk_bytes = EncodedPoint::from(alice_secret.public_key());


// Bob

let bob_secret = EphemeralSecret::random(&mut OsRng);

let bob_pk_bytes = EncodedPoint::from(bob_secret.public_key());


// Alice decodes Bob's serialized public key and computes a shared secret from it

let bob_public = PublicKey::from_sec1_bytes(bob_pk_bytes.as_ref())

    .expect("bob's public key is invalid!"); // In real usage, don't panic, handle this!


let alice_shared = alice_secret.diffie_hellman(&bob_public);


// Bob decodes Alice's serialized public key and computes the same shared secret

let alice_public = PublicKey::from_sec1_bytes(alice_pk_bytes.as_ref())

    .expect("alice's public key is invalid!"); // In real usage, don't panic, handle this!


let bob_shared = bob_secret.diffie_hellman(&alice_public);


// Both participants arrive on the same shared secret

assert_eq!(alice_shared.raw_secret_bytes(), bob_shared.raw_secret_bytes());

ECDH 算法概述(CNG 示例)

Elliptic Curve Diffie-Hellman (ECDH) function

密钥交换算法

图解 ECDHE 密钥交换算法

x25519-dalek X25519 elliptic curve Diffie-Hellman key exchange in pure-Rust, using curve25519-dalek.

密钥管理系统(Key Management Service,KMS)

HashiCorp Vault官网

HashiCorp Vault Github

RustyVault


 

HashiCorp Vault

async fn vault() {
    use vaultrs::client::{Client, VaultClient, VaultClientSettingsBuilder};

    use rand_core::CryptoRngCore;
    use rand_core::OsRng;
    use rsa::pkcs8::{
        self, DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey, LineEnding,
    };
    use rsa::{Pkcs1v15Encrypt, PublicKey, RsaPrivateKey, RsaPublicKey};
    use serde::{Deserialize, Serialize};
    use vaultrs::kv2;
    // let mut rng = random::thread_rng();

    // Create and read secrets
    #[derive(Debug, Deserialize, Serialize)]
    struct MySecret {
        key: String,
        password: String,
    }

    #[derive(Debug, Deserialize, Serialize)]
    struct RSAKey {
        public_key: String,
        private_key: String,
    }

    // Create a client
    let mut client = VaultClient::new(
        VaultClientSettingsBuilder::default()
            .address("http://127.0.0.1:8200")
            .token("hvs.80mEiiPnonTChoSTH5pkAeLg")
            .build()
            .unwrap(),
    )
    .unwrap();

    let secret = MySecret {
        key: "super".to_string(),
        password: "secret".to_string(),
    };
    kv2::set(&client, "secret", "mysecret", &secret).await;

    // let secret: MySecret = ;
    let result: Result<MySecret, vaultrs::error::ClientError> =
        kv2::read(&client, "secret", "mysecret").await;
    if (result.is_ok()) {
        println!("{}", result.unwrap().password) // "secret"
    } else {
        println!("{:?}", result.err()) // "secret"
    }

    let mut public_key = String::new();
    let mut private_key = String::new();

    let bits = 2048;
    let mut rng = rand::thread_rng();
    //1. 生成RSA公私钥
    let priv_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
    let pub_key = RsaPublicKey::from(&priv_key);

    //2. 序列化公私钥
    if let Ok(priv_pem) = RsaPrivateKey::to_pkcs8_pem(&priv_key, pkcs8::LineEnding::default()) {
        private_key = priv_pem.to_string();
    }

    if let Ok(pub_pem) = RsaPublicKey::to_public_key_pem(&pub_key, pkcs8::LineEnding::default()) {
        public_key = pub_pem.to_string();
    }

    let secret1 = RSAKey {
        public_key,
        private_key,
    };

    // let mut rng = rand_core::OsRng;
    let key = String::from("RSA:666666666666");

    kv2::set(&client, "secret", &key, &secret1).await;

    let result: Result<RSAKey, vaultrs::error::ClientError> =
        kv2::read(&client, "secret", &key).await;
    if (result.is_ok()) {
        println!("{}", result.unwrap().public_key)
    } else {
        println!("{:?}", result.err())
    }
}

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值