密码学 - xiangwangfeng/xiangwangfeng.github.io GitHub Wiki

RSA

公私钥生成

  • 随机生成两个质数 p q
  • 计算 n = p * q //模数
  • 计算 λ(n) = (p -1) * (q -1) //欧拉函数
  • 取 e 满足: 1 < e < λ(n),且 e 与 λ(n) 互质 //公钥指数
  • 取 d 满足: (e * d) mod λ(n) = 1 //私钥指数
  • 将 p 和 q 销毁
  • (n,e) 即为公钥,(n,d) 即为私钥

加密过程

f(m) = m^e mod n = c

解密过程

f(c) = c^d mod n = m

openssl


struct rsa_st {
    /*
     * The first parameter is used to pickup errors where this is passed
     * instead of aEVP_PKEY, it is set to 0
     */
    int pad;
    long version;
    const RSA_METHOD *meth;
    /* functional reference if 'meth' is ENGINE-provided */
    ENGINE *engine;
    BIGNUM *n;
    BIGNUM *e;
    BIGNUM *d;
    BIGNUM *p;
    BIGNUM *q;
    BIGNUM *dmp1;
    BIGNUM *dmq1;
    BIGNUM *iqmp;
    /* be careful using this if the RSA structure is shared */
    CRYPTO_EX_DATA ex_data;
    int references;
    int flags;
    /* Used to cache montgomery values */
    BN_MONT_CTX *_method_mod_n;
    BN_MONT_CTX *_method_mod_p;
    BN_MONT_CTX *_method_mod_q;
    /*
     * all BIGNUM values are actually in the following data, if it is not
     * NULL
     */
    char *bignum_data;
    BN_BLINDING *blinding;
    BN_BLINDING *mt_blinding;
};


备注

  • 一般而言 e 都会取某个常数,在 openssl 中定义为 RSA_F4,即 0x10001
  • openssl genrsa 的 man page 中有一段非常让人迷惑的表述,即先通过 genrsa 生成私钥文件,再通过 私钥文件导出公钥文件。而实际上这种描述是不够精准的,让人误以为可以通过私钥导出公钥,而实际情况是在私钥文件中同时包含公私钥对。可以通过 openssl rsa -text pk.pem 查看得知,在私钥文件中 n e d 都存在,详细可以参考这里

AES

  • 块加密
  • 密钥长度可选 128bit,192bit,256bit
  • iv 长度为 128bit
  • iOS 的 CommonCrypto 中没有 PKCS5Padding 定义,可以直接使用 PKCS7Padding 兼容