rsa加密和解密的公式,rsa算法的加密和解密步骤

首页 > 经验 > 作者:YD1662022-10-30 01:53:07

  • **Data:**数据层,定义了RSA密钥的数学概念(m,e,p,q等)或者参与实体(subject, issuer等)。
  • **Serialization:**序列化层,定义了将复杂数据结构序列化的方法。
  • **Structure:**结构层,定义了不同格式的RSA密钥的数据组织形式。
  • **Text:**文本层,定义了将二进制的密钥转换成文本的方法。
  • **Presentation:**表现层,定义了文本格式密钥的表现形式。
  • **Application:**应用层,定义了RSA密钥使用的各种场景。
  • 下面对每一层进行具体说明。

    3.2 数据层

    从上文可知,秘钥是一个数据结构,每个结构包含了 2 个或更多的成员(公钥包含 m 和 e,私钥包含 m,d,e 以及其他一些中间结果)。为了将这些数据结构保存在文件中,需要定义某种格式对秘钥进行序列化。

    3.3 序列化层

    目前常见的定义数据结构的格式包括 JSON 和 XML 等文本格式。

    比如,理论上我们可以把公钥定义为一个 JSON:

    JSON格式密钥

    { "m":"15", "e":"3" }

    或者,也可以把私钥定义为一个 XML:

    <?xml> <key> <module>15</module> <e>3</e> <d>3</d> <p>3</p> <q>5</q> <key>

    但是 RSA 发明的时候,这两种格式都还不存在。因此科学家们选择了当时比较流行的语法格式ASN.1。

    3.3.1 ASN.1

    ASN.1 全称是 Abstract Syntax Notation dot one,(抽象语法记号第1版)。数字1被ISO加在ASN的后边,是为了保持ASN的开放性,可以让以后功能更加强大的ASN被命名为ASN.2等,但至今也没有出现。

    ASN.1描述了一种对数据进行表示、编码、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构,而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序。

    3.3.2 ASN.1 编码规则

    ASN.1的具体语法可以参考维基百科( zh.wikipedia.org/wiki/ASN.1 ),在此只作简要说明。

    ASN.1 中数据类型表示是 T-L-V 的形式:头 2 个字节代表数据类型,接下来的 2 个字节代表字节长度,V 代表具体值。常见的基础类型的值包括 Integer, UTF8String, 复合结构包括 SEQUENCE, SET.秘钥和证书都是 SEQUENCE 类型,而 SEQUENCE 的 type 是 0x30,且长度是大于 127 的,因此第2 个字节是 0x82. ASN.1 编码表示的数据是二进制数据,通常通过 BASE64 转化成字符串保存在 pem 文件中,而 0x3082 经过 BASE64 编码后,就是字符串 MI,因此所有 PEM 文件存储的秘钥开始的前两个字符是 MI。

    BER, CER, DER 是 ASN.1 编码规则。其中 DER(Distinguish Encode Rules) 是无歧义编码规则,保证相同的数据结构产生的序列化结果也相同的。

    ASN.1 只是定义了抽象数据的序列化方式,但是具体的编码还需要进一步定义。

    严格来说,ASN.1 还不是一种定义数据的格式,而是一种语法标准,按照这种标准,可以制定各种各样的格式。

    3.4 结构层

    根据秘钥文件用途不同,以下标准定义了不同的结构来对秘钥数据进行 ASN.1 编码。通常而言,不同格式的秘钥暗示了不同的结构。

  • pkcs#1 用于定义 RSA 公钥、私钥结构
  • pkcs#7 用于定义证书链
  • pkcs#8 用于定义任何算法公私钥
  • pkcs#12 用于定义私钥证书
  • X.509 定义公钥证书
  • 这些格式的具体区别比较参见下文3.5.2

    3.5 表现层

    可以看到 ASN.1 及其编码规则(BER, CER, DER)定义的是二进制规则,保存在文件中也是二进制格式。由于当时的电子邮件标准不支持二进制内容的传输,如果秘钥文件通过电子邮件传输,就需要将二进制文件转换成文本文件。这就是 PEM(Privacy-Enhanced Mail, 私密增强邮件)的由来。因此,PEM 文件中保存的秘钥内容是 ASN.1 编码生成的二进制内容,再进行 base64 编码后的文本。

    另外,为了方便用户识别是何种格式,中文件的首尾加上一行表示身份的文本。PEM 文件一般包含三部分:首行标签,BASE64 编码的文本数据,尾行标签。

    -----BEGIN <label>----- <BASE64 ENCODED DATA> -----END <label>-----

    针对不同的格式, 值不一样。

    3.5.2 PEM 文件格式小结

    rsa加密和解密的公式,rsa算法的加密和解密步骤(5)

    3.6 应用层

    在实际使用中,不仅仅需要使用公私钥对数据进行加解密,还需要根据不同的使用场景,解决密钥的分发、验证等。第5节列举了RSA密钥的一些常见使用场景。

    四、工具4.1 openssl

    注意:下面的命令中-RSAPublicKey_in, -RSAPublicKey_out选项需要openssl1.0以上版本支持,如果报错,请检查 openssl 版本。

    4.1.1 创建秘钥文件

    # 生成 pkcs#1 格式2048位的私钥 openssl genrsa -out private.pem 2048 #从私钥中提取 pkcs#8 格式公钥 openssl rsa -in private.pem -out public.pem -pubout #从私钥中提取 pkcs#1 格式公钥 openssl rsa -in private.pem -out public.pem -RSAPublicKey_out4.1.2 秘钥文件格式转换

    #pkcs#1 公钥转换成 pkcs#8 公钥 openssl rsa -in public.pem -out public-pkcs8.pem -RSAPublicKey_in #pkcs#8 公钥转换成 pkcs#1 公钥 openssl rsa -in public-pkcs8.pem -out public-pkcs1.pem -pubin -RSAPublicKey_out #pkcs#1 私钥转换成 pkcs#8 私钥 openssl pkcs8 -in private.pem -out private-pkcs8.pem -topk8 #pkcs#8 私钥转换成 pkcs#1 私钥 openssl rsa -in private-pkcs8.pem -out private-pkcs1.pem4.1.3 查看秘钥文件信息

    #查看公钥信息 openssl rsa -in public.pem -pubin -text -noout #查看私钥信息 openssl rsa -in private.pem -text -noout4.1.4 证书

    RSA证书

    #从现有私钥创建 CSR 文件 openssl req -key private.pem -out request.csr -new #从现有 CSR 文件和私钥中创建证书,有效期365天 openssl x509 -req -in request.csr -signkey private.pem -out cert.crt -days 365 #生成全新证书和私钥 openssl req -nodes -newkey rsa:2048 -keyout root.key -out root.crt -x509 -days 365 #通 过 现 有 证 书 和 私 钥 (作 为CA ) 为 其 他 CSR 文 件 签 名 openssl x509 -req -in child.csr -days 365 -CA root.crt -CAkey root.key -set_serial 01 -out child.crt #查看证书信息 openssl x509 -in child.crt -text -noout #从证书中提取公钥 openssl x509 -pubkey -noout -in child.crt > public.pem4.1.5 JKS

    #将CA证书转换成JKS格式 keytool -importcert -alias Cacert -file ca.crt -keystore truststoremysql.jks -storepass password123 #将client.crt和client.key转换成PKCS#12格式 openssl pkcs12 -export -in client.crt -inkey client.key -name "mysqlclient" -passout pass:mypassword -out client-keystore.p12 #将PKCS#12格式转换成JKS格式 keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore clientstore.jks -deststoretype JKS -deststorepass password456五、 RSA密钥使用场景5.1 HTTPS单向认证

    由于HTTP协议是明文传输,为了保证HTTP报文不被泄露和篡改,HTTPS通过SSL/TLS协议对HTTP报文进行加解密。

    简单来说,HTTPS协议要求客户端和服务端建立连接的过程中,首先进行会话密钥交换,然后使用该会话密钥对通信报文进行加解密。整个通信过程如下:

    1. 服务端通过4.1.4所示方法创建RSA证书server.crt和私钥server.key,并在WEB服务器中进行配置。
    2. 客户端与服务端建立连接,服务端向客户端发送证书server.crt。
    3. 客户端对服务端证书进行校验,并随机生成会话密钥,将通过服务端证书对会话密钥进行加密,传给服务端。
    4. 服务端通过server.key对加密后的会话密钥进行解密,获得会话密钥原文。
    5. 客户端通过会话密钥对HTTP报文进行加密,传给服务端。
    6. 服务端通过会话密钥对HTTP加密报文进行解密,获得HTTP报文原文。
    7. 服务端通过会话密钥对HTTP响应报文进行加密,返回给客户端。
    8. 客户端通过会话密钥对HTTP响应报文进行解密,获得HTTP响应报文原文。

    rsa加密和解密的公式,rsa算法的加密和解密步骤(6)

    (图1. HTTPS单向认证)

    5.2 HTTPS双向认证

    5.1节描述的HTTPS场景是一个通用场景,整个过程只有客户端对于服务端的验证,即客户端拿到服务端的证书后,会对证书进行有效性验证,比如是否是CA签名的,是否仍处于有效期内等。这种单向验证在浏览器访问等场景中没有问题,因为这种服务设计地目的就是对外数以万计的用户提供服务。但是在某些场景,比如说仅对特定企业、商户提供服务,服务端需要对客户端进行验证,通过验证的受信客户端才能正常。

    访问服务端时,就需要用到HTTPS双向认证。

    HTTPS双向认证的过程,就是在HTTPS单向认证的基础之上,增进服务端对客户端的认证。解决方案的思路就是,客户端保存客户端证书client.crt,但是客户端证书不是客户端自己签名或者CA签名,而是由服务端的root.key进行签名。在HTTPS双向认证过程中,客户端需要将客户端证书client.crt发送给服务端,服务端使用root.key进行验证无误后,方可进行后续通信;否则,该客户端即非受信客户端,服务端拒绝提供后续服务。

    具体通信过程如下所示:

    1. 服务端通过4.1.4所示方法创建RSA证书server.crt和私钥server.key,并在WEB服务器中进行配置。
    2. 客户端与服务端建立连接,服务端向客户端发送证书server.crt。
    3. 客户端对服务端证书进行校验,验证通过后继续后续流程;验证不通过则断开连接,流程结束。
    4. 服务端向客户端发送报文,请求客户端发送客户端证书。
    5. 客户端向服务端发送客户端证书。
    6. 服务端通过root.key对客户端证书进行验证,验证无误进行后续流程;否则断开连接,流程结束。
    7. 客户端随机生成会话密钥,将通过服务端证书对会话密钥进行加密,传给服务端。
    8. 服务端通过server.key对加密后的会话密钥进行解密,获得会话密钥原文。
    9. 客户端通过会话密钥对HTTP报文进行加密,传给服务端。
    10. 服务端通过会话密钥对HTTP加密报文进行解密,获得HTTP报文原文。
    11. 服务端通过会话密钥对HTTP响应报文进行加密,返回给客户端。
    12. 客户端通过会话密钥对HTTP响应报文进行解密,获得HTTP响应报文原文。

    可以看出,向较于HTTPS单向认证过程,HTTPS双向认证过程在客户端验证服务端证书之后,在向服务端发送加密的会话密钥之前,会增加客户端向服务端发送客户端证书client.crt,服务端对该证书进行验证的过程。

    rsa加密和解密的公式,rsa算法的加密和解密步骤(7)

    (图2. HTTPS双向认证)

    5.3 MySQL开启 SSL

    MySQL提供SSL的原理,与HTTPS类似,不同之处在于MySQL提供的服务的对象不会是成千上万的普通用户,因此对于CA的需求并不高。

    因此实际CA证书通常都是服务端自己生成。

    与HTTPS类似,MySQL提供两种形式的SSL认证机制:单向认证和双向认证。

    5.3.1 MySQL的SSL单向认证

    (1)服务端配置文件:ca.crt, server.crt, server.key,其中server.crt由ca.crt签名生成。

    (2)客户端配置文件:ca.crt,ca.crt与服务端的ca.crt相同。

    (3)客户端生成JKS文件

    keytool -importcert -alias Cacert -file ca.crt -keystore truststoremysql.jks -storepass password123

    (4)通过jdbc字符串配置SSL选项和JKS文件

    verifyServerCertificate=true&useSSL=true&requireSSL=true&trustCertificateKeyStoreUrl=file:./truststoremysql.jks&trustCertificateKeyStorePassword=password1235.3.2 MySQL的SSL双向认证

    (1)服务端配置文件:ca.crt, server.crt, server.key, 其中server.crt由ca.crt签名生成。

    (2)客户端配置文件:ca.crt, client.crt, client.key, 其中ca.crt与服务端的ca.crt相同, client.crt由ca.crt签名生成。

    (3)客户端生成trustKeyStore文件

    keytool -importcert -alias Cacert -file ca.crt -keystore truststore.jks -storepass password123

    (4)客户端生成clientKeyStore文件

    keytool -importcert -alias Cacert -file ca.crt -keystore clientstore.jks -storepass password456

    (5)通过jdbc字符串配置SSL选项和JKS文件

    verifyServerCertificate=true&useSSL=true&requireSSL=true&trustCertificateKeyStoreUrl=file:./truststore.jks&trustCertificateKeyStorePassword=password123&clientCertificateKeyStoreUrl=file:./clientstore.jks&clientCertificateKeyStorePassword=password456

    关于MySQL的SSL认证更多细节可以参考:

  • www.howtoforge.com/tutorial/ho…
  • www.cnblogs.com/ccgood/p/13…
  • 附录A 不同格式的 ASN.1 编码A.1 pkcs#1A.1.1 公钥

    RSAPublicKey ::= SEQUENCE { modulus INTEGER , -- n publicExponent INTEGER -- e }

    A.1.2 私钥

    RSAPrivateKey ::= SEQUENCE { version Version , modulus INTEGER , -- n publicExponent INTEGER , -- e privateExponent INTEGER , -- d prime1 INTEGER , -- p prime2 INTEGER , -- q exponent1 INTEGER , -- d mod (p-1) exponent2 INTEGER , -- d mod (q-1) coefficient INTEGER , -- (inverse of q) mod p otherPrimeInfos OtherPrimeInfos OPTIONAL }

    A.2 pkcs#8

    A.2.1 pkcs#8 公钥

    PublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier , PublicKey BIT STRING } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER , parameters ANY DEFINED BY algorithm OPTIONAL }

    A.2.2 pkcs#8 私钥

    OneAsymmetricKey ::= SEQUENCE { version Version , privateKeyAlgorithm PrivateKeyAlgorithmIdentifier , privateKey PrivateKey , attributes [0] Attributes OPTIONAL , ..., [[2: publicKey [1] PublicKey OPTIONAL ]], ... } PrivateKey ::= OCTET STRING -- Content varies based on type of key. The -- algorithm identifier dictates the format of -- the key.A.3 X.509A.3.1 X.509 证书

    Certificate ::= SEQUENCE { tbsCertificate TBSCertificate , signatureAlgorithm AlgorithmIdentifier , signatureValue BIT STRING } TBSCertificate ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, serialNumber CertificateSerialNumber , signature AlgorithmIdentifier , issuer Name, validity Validity , subject Name, subjectPublicKeyInfo SubjectPublicKeyInfo , issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL , -- If present , version MUST be v2 or v3 subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL , -- If present , version MUST be v2 or v3 extensions [3] EXPLICIT Extensions OPTIONAL -- If present , version MUST be v3 } Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= INTEGER Validity ::= SEQUENCE { notBefore Time, notAfter Time } Time ::= CHOICE { utcTime UTCTime , generalTime GeneralizedTime } UniqueIdentifier ::= BIT STRING SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier , subjectPublicKey BIT STRING } Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension Extension ::= SEQUENCE { extnID OBJECT IDENTIFIER , critical BOOLEAN DEFAULT FALSE , extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value -- corresponding to the extension type identified -- by extnID }

    作者:Zhu Ran ,来自vivo互联网技术团队

    出处:https://juejin.cn/post/6919280732917465101

    ,
    上一页12末页

    栏目热文

    文档排行

    本站推荐

    Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.