DH加密算法使用简介

简介: RSA与DH算法的区别,Curve25519椭圆曲线算法的验签逻辑

RSA与DH算法

迪菲—赫尔曼密钥交换是使用和RSA相似的技术吗?

RSA

RSA可以用于加密和签名,用公钥和私钥可以对文件做验证。

但RSA无法解决前向加密的问题,如果RSA的私钥泄漏,之前的消息均可用私钥解密出来。

RSA可以做密钥传输,B使用A的密钥对中的公钥加密数据,只有B用它的私钥才能解开。但RSA的公钥也不能在公网中传递,依然会有被中间人攻击的可能。

DH

DH的使用双方均有一对密钥,如果一方的公钥和私钥泄漏,依然无法破解之前的数据。

DH算法本身不包含身份认证机制,如果AB在交换公钥时被截获,C插入一对DH密钥,分别与AB通信,则可以截取信息。

Curve25519椭圆曲线算法

从 Ed25519 转换为 Curve25519 公钥

Curve25519是一种高水平的DH函数,提供128位的安全心,是最快的ECC曲线。

使用一个32字节的私钥,再根据私钥计算出32字节公钥。

B用户的公钥+A用户的私钥、A用户的公钥+B用户的私钥可以计算出一个32字节的共享密钥提供给两个用户使用,做AES加密。

Ed25519加密解密很快,生成时间短而且安全性更高,rsa则加密解密稍慢,生成时间长,安全性没有ed25519高,只是rsa基本都是默认,所以用的人更多,但是建议转换为ed25519,网站软件现在基本都支持了.

验签逻辑

curve25519_sign

  1. 将 Curve25519的私钥 转换为 Ed25519的公钥
  2. 使用 Curve25519的私钥 和 Ed25519的公钥 对数据进行签名。
  3. 返回加密结果

curve25519_verify

参数:加密数据,Curve25519公钥,原始数据

  1. 将 Cureve25519的公钥 转换成 Ed25519的公钥 。
  2. 使用 Ed25519的公钥 计算出 签名数据,将签名数据从加密数据中提取出来。
  3. 再将原始数据与签名数据拼接生成 验证体数据A 。
  4. 使用 Ed25519的公钥 ,验证体数据A,原始数据,生成 验证体数据B。
  5. 验证解密结果是否成功
void curve25519_keygen(unsigned char* curve25519_pubkey_out,
                       const unsigned char* curve25519_privkey_in)
{
  ge_p3 ed; /* Ed25519 pubkey point */
  fe ed_y, ed_y_plus_one, one_minus_ed_y, inv_one_minus_ed_y;
  fe mont_x;

  /* Perform a fixed-base multiplication of the Edwards base point,
     (which is efficient due to precalculated tables), then convert
     to the Curve25519 montgomery-format public key.  In particular,
     convert Curve25519's "montgomery" x-coordinate into an Ed25519
     "edwards" y-coordinate:

     mont_x = (ed_y + 1) / (1 - ed_y)

     with projective coordinates:

     mont_x = (ed_y + ed_z) / (ed_z - ed_y)

     NOTE: ed_y=1 is converted to mont_x=0 since fe_invert is mod-exp
  */

  ge_scalarmult_base(&ed, curve25519_privkey_in);
  fe_add(ed_y_plus_one, ed.Y, ed.Z);
  fe_sub(one_minus_ed_y, ed.Z, ed.Y);  
  fe_invert(inv_one_minus_ed_y, one_minus_ed_y);
  fe_mul(mont_x, ed_y_plus_one, inv_one_minus_ed_y);
  fe_tobytes(curve25519_pubkey_out, mont_x);
}

int curve25519_sign(unsigned char* signature_out,
                    const unsigned char* curve25519_privkey,
                    const unsigned char* msg, const unsigned long msg_len,
                    const unsigned char* random)
{
  ge_p3 ed_pubkey_point; /* Ed25519 pubkey point */
  unsigned char ed_pubkey[32]; /* Ed25519 encoded pubkey */
  unsigned char *sigbuf; /* working buffer */
  unsigned char sign_bit = 0;

  if ((sigbuf = malloc(msg_len + 128)) == 0) {
    memset(signature_out, 0, 64);
    return -1;
  }

  /* Convert the Curve25519 privkey to an Ed25519 public key */
  ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey);
  ge_p3_tobytes(ed_pubkey, &ed_pubkey_point);
  sign_bit = ed_pubkey[31] & 0x80;

  /* Perform an Ed25519 signature with explicit private key */
  crypto_sign_modified(sigbuf, msg, msg_len, curve25519_privkey,
                       ed_pubkey, random);
  memmove(signature_out, sigbuf, 64);

  /* Encode the sign bit into signature (in unused high bit of S) */
   signature_out[63] &= 0x7F; /* bit should be zero already, but just in case */
   signature_out[63] |= sign_bit;

   free(sigbuf);
   return 0;
}

int curve25519_verify(const unsigned char* signature,
                      const unsigned char* curve25519_pubkey,
                      const unsigned char* msg, const unsigned long msg_len)
{
  fe mont_x, mont_x_minus_one, mont_x_plus_one, inv_mont_x_plus_one;
  fe one;
  fe ed_y;
  unsigned char ed_pubkey[32];
  unsigned long long some_retval;
  unsigned char *verifybuf = NULL; /* working buffer */
  unsigned char *verifybuf2 = NULL; /* working buffer #2 */
  int result;

  if ((verifybuf = malloc(msg_len + 64)) == 0) {
    result = -1;
    goto err;
  }

  if ((verifybuf2 = malloc(msg_len + 64)) == 0) {
    result = -1;
    goto err;
  }

  /* Convert the Curve25519 public key into an Ed25519 public key.  In
     particular, convert Curve25519's "montgomery" x-coordinate into an
     Ed25519 "edwards" y-coordinate:

     ed_y = (mont_x - 1) / (mont_x + 1)

     NOTE: mont_x=-1 is converted to ed_y=0 since fe_invert is mod-exp

     Then move the sign bit into the pubkey from the signature.
  */
  fe_frombytes(mont_x, curve25519_pubkey);
  fe_1(one);
  fe_sub(mont_x_minus_one, mont_x, one);
  fe_add(mont_x_plus_one, mont_x, one);
  fe_invert(inv_mont_x_plus_one, mont_x_plus_one);
  fe_mul(ed_y, mont_x_minus_one, inv_mont_x_plus_one);
  fe_tobytes(ed_pubkey, ed_y);

  /* Copy the sign bit, and remove it from signature */
  ed_pubkey[31] &= 0x7F;  /* bit should be zero already, but just in case */
  ed_pubkey[31] |= (signature[63] & 0x80);
  memmove(verifybuf, signature, 64);
  verifybuf[63] &= 0x7F;

  memmove(verifybuf+64, msg, msg_len);

  /* Then perform a normal Ed25519 verification, return 0 on success */
  /* The below call has a strange API: */
  /* verifybuf = R || S || message */
  /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 
     replaced with pubkey for hashing, then the whole thing gets zeroized
     (if bad sig), or contains a copy of msg (good sig) */
  result = crypto_sign_open(verifybuf2, &some_retval, verifybuf, 64 + msg_len, ed_pubkey);

  err:

  if (verifybuf != NULL) {
    free(verifybuf);
  }

  if (verifybuf2 != NULL) {
    free(verifybuf2);
  }

  return result;
}
目录
相关文章
|
3月前
|
存储 算法 安全
【加密算法】AES对称加密算法简介
【加密算法】AES对称加密算法简介
|
3月前
|
机器学习/深度学习 算法 安全
【加密算法】RSA非对称加密算法简介
【加密算法】RSA非对称加密算法简介
|
10月前
|
监控 算法 安全
二进制转十进制算法简介及其在监控软件中的应用
在上网行为管理软件中,匈牙利算法主要应用于解决资源分配的问题。上网行为管理软件可能存在多个用户同时访问同一文件或打印机的情况,为了确保资源的公平共享,需要对资源进行分配
201 2
|
3月前
|
机器学习/深度学习 算法 TensorFlow
机器学习算法简介:从线性回归到深度学习
【5月更文挑战第30天】本文概述了6种基本机器学习算法:线性回归、逻辑回归、决策树、支持向量机、随机森林和深度学习。通过Python示例代码展示了如何使用Scikit-learn、statsmodels、TensorFlow库进行实现。这些算法在不同场景下各有优势,如线性回归处理连续值,逻辑回归用于二分类,决策树适用于规则提取,支持向量机最大化类别间隔,随机森林集成多个决策树提升性能,而深度学习利用神经网络解决复杂模式识别问题。理解并选择合适算法对提升模型效果至关重要。
211 4
|
6天前
|
算法
【算法】贪心算法简介
【算法】贪心算法简介
|
6天前
|
算法
【算法】递归、搜索与回溯——简介
【算法】递归、搜索与回溯——简介
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
算法金 | 秒懂 AI - 深度学习五大模型:RNN、CNN、Transformer、BERT、GPT 简介
**RNN**,1986年提出,用于序列数据,如语言模型和语音识别,但原始模型有梯度消失问题。**LSTM**和**GRU**通过门控解决了此问题。 **CNN**,1989年引入,擅长图像处理,卷积层和池化层提取特征,经典应用包括图像分类和物体检测,如LeNet-5。 **Transformer**,2017年由Google推出,自注意力机制实现并行计算,优化了NLP效率,如机器翻译。 **BERT**,2018年Google的双向预训练模型,通过掩码语言模型改进上下文理解,适用于问答和文本分类。
87 9
|
29天前
|
算法
Raid5数据恢复—Raid5算法简介&raid5磁盘阵列数据恢复案例
Raid5算法也被称为“异或运算”。异或是一个数学运算符,它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。异或的运算法则为:a⊕b = (¬a ∧ b) ∨ (a ∧¬b)。如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。 异或也叫半加运算,其运算法则相当于不带进位的二进制加法。二进制下用1表示真,0表示假。异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。 异或略称为XOR、EOR、EX-OR,程序中有三种演算子:XOR、xor、⊕。使用方法如下z = x ⊕ y z
Raid5数据恢复—Raid5算法简介&raid5磁盘阵列数据恢复案例
|
3月前
|
缓存 算法 Java
Linux内核新特性年终大盘点-安卓杀后台现象减少的背后功臣MGLRU算法简介
MGLRU是一种新型内存管理算法,它的出现是为了弥补传统LRU(Least Recently Used)和LFU(Least Frequently Used)算法在缓存替换选择上的不足,LRU和LFU的共同缺点就是在做内存页面替换时,只考虑内存页面在最近一段时间内被访问的次数和最后一次的访问时间,但是一个页面的最近访问次数少或者最近一次的访问时间较早,可能仅仅是因为这个内存页面新近才被创建,属于刚刚完成初始化的年代代页面,它的频繁访问往往会出现在初始化之后的一段时间里,那么这时候就把这种年轻代的页面迁移出去
|
3月前
|
算法 关系型数据库 C语言
卡尔曼滤波简介+ 算法实现代码(转)
卡尔曼滤波简介+ 算法实现代码(转)
45 4