虫术 虫术
首页
目录
  • 国内验证码

    • 顶象 DING XIANG
    • 数美 NEXTDATA
    • 易盾 NETEASE YIDUN
    • 极验 GEETEST
    • 阿里云云盾验证码
    • 腾讯天御 T-Sec
    • 小红书 redCaptcha
    • 小盾 XIAODUN
    • 云片 YUNPIAN
    • 三六零天御
    • 螺丝帽 Luosimao
    • Vaptcha
    • V5 验证
    • 凯格 KYGER
    • 友验 FastYotest
  • 国外验证码

    • Cloudflare Turnstile
    • Google reCAPTCHA
    • hCaptcha
    • Arkose Labs FunCAPTCHA
    • DataDome CAPTCHA
    • PerimeterX丨HUMAN Challenge
    • AWS (Amazon) WAF Captcha
    • MTCaptcha
    • Lemin CAPTCHA丨Capy Puzzle
    • Yandex SmartCaptcha
    • mCaptcha
    • KeyCAPTCHA
    • CyberSiARA
    • Friendly Captcha
    • ARCaptcha
    • CaptchaFox
  • 辅助脚本

    • JS Hook
    • Frida API
    • babel
  • 命令查询

    • Linux 命令
    • ADB 命令
    • ARM 指令集
    • Dalvik 指令集
  • 指纹信息

    • CreepJS
    • Fingerprint2
    • 自动化工具检测
  • 加密算法

    • URL
    • Unicode
    • Base64
    • MD5
    • HMAC
    • SHA
    • RSA
    • AES
    • DES
    • 3DES
    • RC4
    • SM
  • 基本请求

    • Python
  • 异步协程

    • asyncio
    • gevent
  • 多线程

    • threading
    • vthread
  • 多进程

    • multiprocessing
  • 自动化框架

    • selenium
    • pyppeteer
    • playwright
    • splash
    • DrissionPage
    • appium
    • airtest
  • 接口编写

    • FastAPI
    • flask
    • express
  • 爬虫框架

    • scrapy
    • feapder
    • pyspider
  • 数据提取

    • re
    • lxml
    • BeautifulSoup
    • pyquery
    • selectolax
  • 数据分析

    • wordcloud
    • jieba
    • pandas
    • NumPy
    • SciPy
  • 制表绘图

    • matplotlib
    • pyecharts
    • plotly
    • seaborn
  • 数据存储

    • 文件存储
    • MySQL
    • MongoDB
    • Redis
    • SQLite
悟空风控
赞助
GitHub (opens new window)
首页
目录
  • 国内验证码

    • 顶象 DING XIANG
    • 数美 NEXTDATA
    • 易盾 NETEASE YIDUN
    • 极验 GEETEST
    • 阿里云云盾验证码
    • 腾讯天御 T-Sec
    • 小红书 redCaptcha
    • 小盾 XIAODUN
    • 云片 YUNPIAN
    • 三六零天御
    • 螺丝帽 Luosimao
    • Vaptcha
    • V5 验证
    • 凯格 KYGER
    • 友验 FastYotest
  • 国外验证码

    • Cloudflare Turnstile
    • Google reCAPTCHA
    • hCaptcha
    • Arkose Labs FunCAPTCHA
    • DataDome CAPTCHA
    • PerimeterX丨HUMAN Challenge
    • AWS (Amazon) WAF Captcha
    • MTCaptcha
    • Lemin CAPTCHA丨Capy Puzzle
    • Yandex SmartCaptcha
    • mCaptcha
    • KeyCAPTCHA
    • CyberSiARA
    • Friendly Captcha
    • ARCaptcha
    • CaptchaFox
  • 辅助脚本

    • JS Hook
    • Frida API
    • babel
  • 命令查询

    • Linux 命令
    • ADB 命令
    • ARM 指令集
    • Dalvik 指令集
  • 指纹信息

    • CreepJS
    • Fingerprint2
    • 自动化工具检测
  • 加密算法

    • URL
    • Unicode
    • Base64
    • MD5
    • HMAC
    • SHA
    • RSA
    • AES
    • DES
    • 3DES
    • RC4
    • SM
  • 基本请求

    • Python
  • 异步协程

    • asyncio
    • gevent
  • 多线程

    • threading
    • vthread
  • 多进程

    • multiprocessing
  • 自动化框架

    • selenium
    • pyppeteer
    • playwright
    • splash
    • DrissionPage
    • appium
    • airtest
  • 接口编写

    • FastAPI
    • flask
    • express
  • 爬虫框架

    • scrapy
    • feapder
    • pyspider
  • 数据提取

    • re
    • lxml
    • BeautifulSoup
    • pyquery
    • selectolax
  • 数据分析

    • wordcloud
    • jieba
    • pandas
    • NumPy
    • SciPy
  • 制表绘图

    • matplotlib
    • pyecharts
    • plotly
    • seaborn
  • 数据存储

    • 文件存储
    • MySQL
    • MongoDB
    • Redis
    • SQLite
悟空风控
赞助
GitHub (opens new window)
bright data bright data

(进入注册为作者充电)

  • 辅助脚本

    • JS Hook
    • Frida API
    • Babel
  • 命令查询

    • Linux 命令
    • ADB 命令
    • ARM 指令集
    • Dalvik 指令集
  • 指纹信息

    • CreepJS
    • Fingerprint2
    • 自动化工具检测
  • 加密算法

    • URL
    • Unicode
    • Base64
    • MD5
    • HMAC
    • SHA
    • RSA
      • 生成密钥
        • Python
        • JavaScript
        • Golang
      • 解析密钥
        • Python
        • JavaScript
        • Golang
      • 转换密钥
        • Python
        • JavaScript
        • Golang
      • 加密解密
        • Python
        • JavaScript
        • Golang
      • 在线工具
    • AES
    • DES
    • 3DES
    • RC4
    • SM
目录

RSA

关于 RSA 非对称加密算法

RSA 加密算法是一种非对称加密算法,是由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在 1977 年一起提出的,RSA 就是他们三人姓氏开头字母拼在一起组成的。RSA 公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

RSA 维基百科 (opens new window)

注意

RSA 加解密涉及到密钥位数、密钥格式、密钥语法标准、填充方式等概念,请务必理解后再进行使用,否则可能在使用代码时发生各种报错,认真阅读文档,可解决 99% 的问题!!!

# 生成密钥

关于密钥各个术语的解释

什么是密钥的位数:

该位数既不是指公钥的长度,也不是私钥的长度,实际上是指生成的 RSA 密钥对中公钥和私钥所包含的模数(modulus)的位数,给定一个公钥或者私钥,均可从中解析出模数,由于 RSA 密钥对是基于一个大素数乘积生成的,因此长度也决定了其安全性和加密强度,在实际使用中,密钥位数常见的有 512 位、1024 位、2048 位、3072 位和 4096 位。但实际应用中不推荐 512 位,需要注意的是,密钥长度越长,加密的强度也就越强,但同时也会增加程序计算的时间。例如,秘钥长度增加 1 倍,密钥对生成的时间就增加 16 倍,公钥加密操作时长增加 4 倍,私钥解密操作时长增加 8 倍。因此,选择密钥长度时需要综合考虑安全性和效率。


什么是模数(modulus):

RSA 密钥的模数是公钥和私钥中的一个重要参数,通常用大素数的乘积表示,在 RSA 加密算法中,模数(modulus)是两个大素数的乘积,通常用 N 表示,在密钥生成过程中,选择两个大素数 p 和 q,然后计算它们的乘积 ,这个 N 就是 RSA 密钥的模数,模数 N 用于 RSA 算法中的加密、解密、签名和验证过程,公钥由模数 N 和公钥指数 e 组成,私钥由模数 N 和私钥指数 d 组成。模数 N 的长度通常决定了 RSA 密钥的安全性。


什么是公钥 / 私钥指数:

在 RSA 加密算法中,公钥和私钥都包含一个指数,这些指数是用来进行加密和解密操作的,公钥指数通常用 e 表示,私钥指数通常用 d 表示,这两个指数的选择是相互关联的,确保了 RSA 算法的正确性,通常情况下,公钥指数 e 和私钥指数 d 满足以下条件:,其中 是欧拉函数,用于计算与模数 N 互素的正整数个数。这个条件保证了 RSA 加密和解密过程是可逆的,公钥指数 e 通常为 65537(0x10001,5bits),该值是除了 1、3、5、17、257 之外的最小素数,私钥指数 d 可以通过公钥指数 e 和模数 N 计算得到,一种常用的方法是使用扩展的欧几里得算法或模反演算法,这两种方法都可以有效地计算私钥指数 d,根据前面提到的两个指数关系的公式,可以得到:,所以私钥指数 d 应当是一个大整数,并且满足 。一般在各个 RSA 加解密代码里,都不用单独设置这公钥指数,基本上都是默认的 65537(0x10001,5bits)。


私钥签名(加密):

私钥签名,也称为私钥加密,私钥通常用于对敏感数据进行解密,如果私钥未经授权的访问者获得,可能会导致数据泄露或伪造签名等安全问题,通过加密私钥,即使未经授权的人获得了密钥文件,也需要正确的解密密码才能访问私钥,从而保护私钥的安全。在生成密钥对时,可以指定加密私钥的算法和密码,在使用私钥时,需要提供正确的解密密码才能解密私钥。


密钥输出的格式:

  • der:二进制数据,序列化 ASN.1 (opens new window) 结构;
  • pem:最常见的类型,将 der 数据进行 base64 编码,然后加上以 ----- 包裹的标头,用于标识密钥类型;
  • jwk:JSON Web 密钥,关键数据存储在 JSON 对象中,是 JavaScript 对象签名和加密 (JOSE) 规范的一部分;
  • openssh:OpenSSH 密钥格式,常用于在 OpenSSH 客户端和服务器之间传输密钥,密钥以 ssh-rsa 开头。

密钥的语法标准:

  • 公钥语法标准:pkcs1 或 spki
  • 私钥语法标准:pkcs1 或 pkcs8

有的库里面(如:JS 的 node-rsa 库),公钥语法标准支持 pkcs1 或 pkcs8,没有 spki,事实上这是不太规范的说法,参见 issues (opens new window)。

当密钥输出格式为 pem 时:

  • 公钥使用 pkcs1 标准,得到的公钥以 -----BEGIN RSA PUBLIC KEY----- 开头;
  • 公钥使用 spki 标准,得到的公钥以 -----BEGIN PUBLIC KEY----- 开头;
  • 私钥使用 pkcs1 标准,得到的私钥以 -----BEGIN RSA PRIVATE KEY----- 开头;
  • 私钥使用 pkcs8 标准,得到的私钥以 -----BEGIN PRIVATE KEY----- 开头。
  • 私钥使用 pkcs1 标准,如果对私钥进行了加密,则得到的私钥以 -----BEGIN RSA PRIVATE KEY----- 开头,但内容里包含 Proc-Type、DEK-Info 字段;
  • 私钥使用 pkcs8 标准,如果对私钥进行了加密,则得到的私钥以 -----BEGIN ENCRYPTED PRIVATE KEY----- 开头。

pkcs 标准科普:

公钥加密标准(Public Key Cryptography Standards, PKCS) (opens new window),是由美国 RSA 数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。PKCS#1 至 PKCS#15 是不同类型的标准,用于不同的场景,在 RSA 算法中主要会用到 PKCS#1 和 PKCS#8 两种标准:

  • PKCS#1:专门针对 RSA 算法的一个标准,用于 RSA 公钥和私钥的具体实现以及加密、签名算法的规定;
  • PKCS#8:通用私钥语法标准,定义了私钥的存储格式,可以用于不同密码学算法的私钥存储。

spki 标准科普:

  • 公开密钥基础设施(Public Key Infrastructure, PKI) (opens new window),又称公开密钥基础架构、公钥基础建设、公钥基础设施、公开密码匙基础建设或公钥基础架构,是一组由硬件、软件、参与者、管理政策与流程组成的基础架构,其目的在于创造、管理、分配、使用、存储以及撤销数字证书;
  • 简单公钥基础设施(Simple public-key infrastructure, SPKI) (opens new window),是克服传统 X.509 PKI 复杂性的一种尝试,SPKI 规范定义了授权证书格式,提供了特权、权利或其他此类属性(称为授权)的描述,并将它们绑定到公钥。

【实用参考资料】

公钥证书编码解读:https://zhuanlan.zhihu.com/p/77329250 (opens new window)
RSA密钥长度、明文长度和密文长度:https://cloud.tencent.com/developer/article/1199963 (opens new window)
安全:深入理解数字证书中的 PKCS#1 与 PKCS#8 标准 :https://cloud.tencent.com/developer/article/2390956 (opens new window)
PKCS#1、PKCS#5、PKCS#7、PKCS#8 到底是什么?:https://blog.csdn.net/weixin_45264425/article/details/127096145 (opens new window)

# Python 3.0+


    # ✅ 安装依赖 pip install pycryptodome,官方文档:https://pycryptodome.readthedocs.io/
    
    # ❌ 密钥输出格式不支持 jwk
    # ❌ 公钥语法标准不支持 pkcs1,仅支持 spki
    # ❌ 私钥加密:当私钥语法标准为 pkcs1 时,不支持指定算法,默认使用 DES-EDE3-CBC
    #             当私钥语法标准为 pkcs8 时,protection 可以指定算法,算法名称参考:https://pycryptodome.readthedocs.io/en/latest/src/io/pkcs8.html#encryption-parameters
    
    from Crypto.PublicKey import RSA
    
    
    key = RSA.generate(
        bits=2048,                           # 密钥位数,即模数(modulus)的位数,常见的有 512 位、1024 位、2048 位、3072 位和 4096 位
        e=65537                              # 公钥指数,默认 65537(0x10001),该值是除了 1、3、5、17、257 之外的最小素数
    )
    
    private_key = key.export_key(
        format="PEM",                        # 私钥输出格式,支持 pem、der、openssh
        pkcs=8,                              # 私钥语法标准,支持 pkcs1、pkcs8,该参数仅对私钥有效
        # passphrase="spiderapi",            # 可选参数,私钥加密的密码,如果私钥加密了,则使用时需要先解密,该参数仅对私钥有效
        # protection="scryptAndAES128-GCM",  # 可选参数,私钥加密的算法,该参数仅对私钥,且 pkcs=8 时有效
    )
    public_key = key.publickey().export_key(
        format="PEM",                        # 公钥输出格式,支持 pem、der、openssh,公钥语法标准,仅支持且默认 spki
    )
    
    print("RSA 公钥(spki、pem):\n\n", public_key.decode("utf-8"))
    print("RSA 私钥(pkcs8、pem):\n\n", private_key.decode("utf-8"))
    
    """
    RSA 公钥(spki、pem):
    
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4MIESlYLQMhXeh1AsIxi
    XqdbyG6hMo7feRu2CsvH14iYdwaxMZ2gV3PBu+Z9gCD+zoreO4PYMqpn0koXGg2n
    VRhTZVzJARVnLokmK3wVFYx2ooubABFv/duL30LzHi2qheXIz5etB0XjOPz1A9D3
    OngaHH6YnyoCos0KtDbaiNOdYY2lh5tXG8JV4yaHGmPgHLYjp19EBOYaqiXj89Ut
    GtTvc/bl6pO1uZbsR70zZY2yU79+B7UGhsMHTcFdZ7XokLk2uwUoKRYvsD1S/pEX
    xIYwq1DJZ4/SMAidVe58jwPEg9Vonb/HZX24l35PSDDKC52oUaEynQcdvnHJoJM9
    hwIDAQAB
    -----END PUBLIC KEY-----
    
    RSA 私钥(pkcs8、pem):
    
    -----BEGIN PRIVATE KEY-----
    MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDgwgRKVgtAyFd6
    HUCwjGJep1vIbqEyjt95G7YKy8fXiJh3BrExnaBXc8G75n2AIP7Oit47g9gyqmfS
    ShcaDadVGFNlXMkBFWcuiSYrfBUVjHaii5sAEW/924vfQvMeLaqF5cjPl60HReM4
    /PUD0Pc6eBocfpifKgKizQq0NtqI051hjaWHm1cbwlXjJocaY+ActiOnX0QE5hqq
    JePz1S0a1O9z9uXqk7W5luxHvTNljbJTv34HtQaGwwdNwV1nteiQuTa7BSgpFi+w
    PVL+kRfEhjCrUMlnj9IwCJ1V7nyPA8SD1Widv8dlfbiXfk9IMMoLnahRoTKdBx2+
    ccmgkz2HAgMBAAECggEACSTA0Zi0MX5VAgycRp0XcrwClwyvyyOWgidMncjSMvmw
    INt+rELk3y9AOO7fY9iJH970u91ubLU+WbGWRK2R2qY4MlNMLBqc+CmFNNdXRj6m
    JDu4t7p94LPPT2sPrUZ0qFODpV+0HtZ1hX/TpJmaN+CN82MlE13n/eEzPRykLFUY
    DVhXcVYlMamHCtNT9039ByEBF7kIeODhLPYgKAcwCOY8f4fQqEDZUfshbHdOlAt+
    Bx9bOToSPqNYMIrzHk/SrUfjI2+x3mVZY5PSSxyBRObroKVd4V+De+bXUyLhdnpC
    RmH8JWsFEcfSILMSlkrfA+xGag36oXTD8wtf19X9XQKBgQDqMQ+B3fiicVLirdLx
    PB0OD4U2noitzkyjr+qZYx3VpIRu+eK1q9esJ9KYzBUEdfTCXaKHHVcjZ/IErOsZ
    eFcBS2Fwwpa3GMeOJ4hTcNuzBIsp6D/g6PwSF4I/lGXTSCep7YEgoana3VItKlqx
    FbweB1guMpzS0jpWKVAPFAG3KwKBgQD1sBAXTqZqXcaVLkgZaowdFA2maFDpNp0b
    tiyGcyRAhYHdbb4TBFrgSDCYdnMpQMo0H4YmqRQFI38r5ROOsSQDcTNwMf6E9nUX
    QlZu1DBri0vnGgbjRTuKIDUEadVrCepCHfYyX7yEMg1vkCqdoknqFICn38R48Gq9
    Ab66m+IlFQKBgBv3M9TcPt6XDcDH5RKtjQKq08uL7uJiakB5t1gNv/hNJwthh7MO
    DDkgoENiy3e25j13lPrxhABUX1AznfdyqWEcMUyX0AuZR+svyVW9el7MQhoFA+vF
    pqQ6bnFNNUOfsCzYkbzl0TSzjSabkiznXYlwcxVBMfzy4ch8MnU6fGH1AoGAZg3/
    cR8Lg412istRybT3hLCqxt/4FBfKhRNURXkYqvCKNEd8t/uMIDP8c6hoR8+Q7rvV
    hsOe/E91aO9cA17TvdZM7qLlvad+le3JZ3oert2K5vFpwQgmJkcgnrezniXdOB+n
    /97CuQrth9UTzqz2FRT1KEaMH0yGmgJajrtn4c0CgYA7N7XM7oI6oH5uG0c2bcNT
    oF6CbMKKY6IRmpyrTeozRrNo/luA0v89o6ETdeC/hChzVh66oECz9KW/XVXFyttt
    8sOTwXEsdWE4A7oNOM1vQhx7DtKJpqtvZFAxrVhgYyuaZSAEc2isWKhIPWq2mjKD
    pByL7lrJPDv9Z7za63nMBQ==
    -----END PRIVATE KEY-----
    """
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    # ✅ 安装依赖 pip install cryptography,要求 Python 3.7+,官方文档:https://cryptography.io/
    
    # ❌ 密钥输出格式不支持 jwk
    # ❌ 私钥语法标准不支持 pkcs1
    
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography.hazmat.primitives import serialization
    from cryptography.hazmat.primitives.ciphers import algorithms
    
    
    private_key = rsa.generate_private_key(
        public_exponent=65537,                                 # 公钥指数,推荐 65537(0x10001),该值是除了 1、3、5、17、257 之外的最小素数
        key_size=2048                                          # 密钥位数,即模数(modulus)的位数,常见的有 512 位、1024 位、2048 位、3072 位和 4096 位
    )
    
    # 从私钥中提取公钥
    public_key = private_key.public_key()
    
    # 序列化私钥和公钥
    public_key = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,                    # 公钥输出格式,支持 pem、der、openssh
        format=serialization.PublicFormat.SubjectPublicKeyInfo  # 公钥语法标准,支持 pkcs1、spki (SubjectPublicKeyInfo)
    )
    
    
    private_key = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,                    # 私钥输出格式,支持 pem、der、openssh
        format=serialization.PrivateFormat.PKCS8,               # 私钥语法标准,支持 pkcs8
        encryption_algorithm=serialization.NoEncryption()       # 私钥不加密
        # encryption_algorithm=serialization.BestAvailableEncryption("password".encode())  # 对私钥加密
    )
    
    print("RSA 公钥(spki、pem):\n\n", public_key.decode("utf-8"))
    print("RSA 私钥(pkcs8、pem):\n\n", private_key.decode("utf-8"))
    
    
    """
    RSA 公钥(spki、pem):
    
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunWw+FBw3WGzKuU9tyoP
    0UWn0FOD5N7vlfhjFn0FUkeMQlgPqj+4uxNnayMA4Qxj9UeMS/N9+dN8KfIWnvjg
    R+UBsSgqZuy/ONx9E23ycq6l2RjGbdIKcRSsmmEKcAjCQub/EglWhzhacwLB4nr/
    HQvQS2x/J5NwR9WD8VWoYPICIa+LUSNZAbbA29Fitj7njbJkJbhNX4aaHUSQpWFG
    djoFyGmpXb1HhaswmaC1jtZo5xzQfuSIeCq21VNWS2wvKdqcHg7jNbhhst54H3W5
    O7Qg7IYiGseYLO2m6f4NxLuhFDfdDHjSNDONzgGvm1fAI1Xs1r01BTx0n3DfSbqz
    AQIDAQAB
    -----END PUBLIC KEY-----
    
    RSA 私钥(pkcs8、pem):
    
    -----BEGIN PRIVATE KEY-----
    MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6dbD4UHDdYbMq
    5T23Kg/RRafQU4Pk3u+V+GMWfQVSR4xCWA+qP7i7E2drIwDhDGP1R4xL833503wp
    8hae+OBH5QGxKCpm7L843H0TbfJyrqXZGMZt0gpxFKyaYQpwCMJC5v8SCVaHOFpz
    AsHiev8dC9BLbH8nk3BH1YPxVahg8gIhr4tRI1kBtsDb0WK2PueNsmQluE1fhpod
    RJClYUZ2OgXIaaldvUeFqzCZoLWO1mjnHNB+5Ih4KrbVU1ZLbC8p2pweDuM1uGGy
    3ngfdbk7tCDshiIax5gs7abp/g3Eu6EUN90MeNI0M43OAa+bV8AjVezWvTUFPHSf
    cN9JurMBAgMBAAECggEBAKydjcKjvYjFDLf2V0b88n27LVsIJb84v7Ynp5vHC6kb
    QXadzYq/yQWvNfuSARtWfCczIGejuAkSxwyR6G0tW3xTPljCJVb5byF1xXi6PUv7
    8N9lNzWt0CrVh+C3W5FSGn0TGimZaXhvLBTzBYjkcs5yBFf+zkxWCwkFWkuOD/4G
    F9sCAzdrxbHkn1qpbPBCf4NIJ3ETApD3AMFuZol+GzAz1E6xaCupCqf1+yjWGjhE
    VjPA6MPx/RqPxI/Xn2BsX9nNEfsyxHmffbG9Hnu487ByOZFOdw/5JWsgCuhnX/0I
    cERAhuuXtjya9NuJkMrXGnoXofc7Om79oE0blcXSb60CgYEA5vhlGkaXeduFHJNa
    2ATDXrYGO1vEYR3fmxUKE7VYjGWZBzaUAQBFc+KFlpj6/587Hyldi6xG+PUWrMzS
    nMDSEgZY+3WdyE9DmUOjp2Mf8sPQYRob3T7osL7ttyaMB5Fv+Rap/HuRla/2FAR7
    77nvFsaGmUW+w4YuVWxKjUcVWMsCgYEAzqp6qBdFugCXwZyIasucqI2DKOocnfbR
    Rbk0lcpyz2Fl6CqPUc1eJUesoOxZuvShMGpeqWPwiD97lsI6BJ5P7ymalR3XaGBr
    nNineop0a2sxj4cbEEcxOXJfl46+MDmDY9n0kOFzULwm0cP1m0VFjMmTLXGnsCRZ
    SVQFGMATBeMCgYBhF/54Y0B+K3fzoUZJFQeEIwTPoy4UnVhIezm3Oz60FmmUDK9/
    FDweERWTT1AEcU2LNfprIsrbETys+5V16+DjTuPNIY5ojFmgbjy3uwXNKd/JUg5w
    nWd4FWsc2Ql4jP0DOzHOP6vdvxC1LYVkK0eEzYP7nsQosZl8s39LkJw6rQKBgFYh
    8zDvUh4tdRI6XRi1d7tAD3QT7o1feuTmRaZQU/1eiIx0gHsFbsF219nR56vlnPCC
    xKUwg+UlICs7E9cs6/+vhT+0yjw0Q2WBXnvSDKdga614D61/HmLk6jZORbHvpnUN
    N8LSU69IW519YHWwL0Z4FKESB2OAIr5PCDjChKslAoGBAIe5+HFJyOZTt3Urzwzc
    7h8q97z+DXRChzTiBv8KaM3hknmKYc9qoGpOK6FqM8GcotvI55ZGlixJtmy1GMRf
    nk1qENc23oadYBEzAcQA5+0me/QDxk0q0BdkDkaNH2NA6lMY/4TriNde/fSY7Dil
    bDVst9Y7yqL41PYRWM/rhWas
    -----END PRIVATE KEY-----
    """
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    # ✅ 安装依赖 pip install rsa,官方文档:https://stuvel.eu/python-rsa-doc/
    
    # ❌ 密钥输出格式不支持 jwk、openssh
    # ❌ 公钥语法标准不支持 spki
    # ❌ 私钥语法标准不支持 pkcs8
    # ❌ 不支持对私钥进行签名、加密
    
    import rsa
    
    
    (public_key, private_key) = rsa.newkeys(
        nbits=1024,        # 密钥位数,即模数(modulus)的位数,常见的有 512 位、1024 位、2048 位、3072 位和 4096 位
        exponent=65537     # 公钥指数,默认 65537(0x10001),该值是除了 1、3、5、17、257 之外的最小素数
    )
    
    # 公钥和私钥输出各种都仅支持 pem 和 der,语法标准都只支持 pkcs1
    public_key = public_key.save_pkcs1(format="PEM")
    private_key = private_key.save_pkcs1(format="PEM")
    
    print("RSA 公钥(pkcs1、pem):\n\n", public_key.decode("utf-8"))
    print("RSA 私钥(pkcs1、pem):\n\n", private_key.decode("utf-8"))
    
    """
    RSA 公钥(pkcs1、pem):
    
    -----BEGIN RSA PUBLIC KEY-----
    MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
    C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
    1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
    -----END RSA PUBLIC KEY-----
    
    RSA 私钥(pkcs1、pem):
    
    -----BEGIN RSA PRIVATE KEY-----
    MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
    lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
    MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
    AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
    r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
    vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
    UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
    SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
    KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
    cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
    PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
    +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
    NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
    -----END RSA PRIVATE KEY-----
    """
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    // Make sure to add code blocks to your code group

    # JavaScript Node.js ECMAScript 5.1+


      // ✅ Node.js 内置 crypto 模块,无需单独安装
      
      // ❌ 密钥输出格式不支持 openssh
      
      var crypto = require("crypto");
      
      
      var { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
          modulusLength: 1024,            // 密钥位数,即模数(modulus)的位数,常见的有 512 位、1024 位、2048 位、3072 位和 4096 位
          publicExponent: 65537,          // 公钥指数,默认 65537(0x10001),该值是除了 1、3、5、17、257 之外的最小素数
              publicKeyEncoding: {
              type: "spki",               // 公钥语法标准,支持 pkcs1、spki
              format: "pem"               // 公钥输出格式,支持 pem、der、jwk
          },
          privateKeyEncoding: {
              type: "pkcs1",              // 私钥语法标准,支持 pkcs1、pkcs8
              format: "pem",              // 私钥输出格式,支持 pem、der、jwk
              // cipher: "aes-256-cbc",   // 可选参数,私钥加密的算法,如 aes-256-cbc、des-ded3-cbc 等,如果私钥加密了,则使用时需要先解密
              // passphrase: "spiderapi"  // 可选参数,私钥加密的密码
          }
      });
      
      console.log("RSA 公钥(spki、pem):\n\n", publicKey);
      console.log("RSA 私钥(pkcs1、pem):\n\n", privateKey);
      
      
      /*
      RSA 公钥(spki、pem):
      
      -----BEGIN PUBLIC KEY-----
      MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDki91MwofoyFW+TPdkDLjvww9q
      GjKzgzbEhTUrl5qBwjWQo/yr1nhbTC4i9Qso8XJS8350cwz2ixbkE0QJgdPtL8d2
      lLUIVDxTy8uAFITvYie7rHNanjPyB2ytnm8p85EyYKZnAlq5V3w9hNAM5XxGnffi
      y4PiS7OlhAdVLZM32QIDAQAB
      -----END PUBLIC KEY-----
      
      RSA 私钥(pkcs1、pem):
      
      -----BEGIN RSA PRIVATE KEY-----
      MIICXQIBAAKBgQDki91MwofoyFW+TPdkDLjvww9qGjKzgzbEhTUrl5qBwjWQo/yr
      1nhbTC4i9Qso8XJS8350cwz2ixbkE0QJgdPtL8d2lLUIVDxTy8uAFITvYie7rHNa
      njPyB2ytnm8p85EyYKZnAlq5V3w9hNAM5XxGnffiy4PiS7OlhAdVLZM32QIDAQAB
      AoGBAJon0QxOhne4cUVcCt5cSn3Gl2Yc56f30IA7zYJqztfJVHIMeoi5sBL8zn3b
      xTxHp7JV9Sy80biWVsleSV0USgoDCkTZqgJTq7pTeUg+LTRSplPb00sm1/gyS7fU
      vwYtCDA8E/4NaG+gCdHAH4TDUOy2JPXF4L3VOBiDpaB+aB0BAkEA8f1qIOWQv7EY
      QNPdbMx9+/2miR/DoPtyyus1Nb+FTNzcZE0/JP8NLJUh7cBhtvRRi0RzhsOYMwK6
      ypCUDZ4Q+QJBAPHHMzOiFlqIedrgZxiGUTZiGovMhBd3OKVYJj8Zr7BbM7TBkf9o
      U3v0LgMhFV7DEt/JXcwlexKmudYufyyo9eECQBwh7OukJJ7UdNBckRpr752TEIBS
      jAi0EtVaYNY9zL5x0sFqZZPkfuCW+dnNCs8dOjmpnJCnPpN3lsWj50JqBOkCQQDq
      rh0v6AvkkoYdAyZu8qlPrUfxHHG2yT1NmNN++jLDbrMwp5dMH3qxXWFwHiO9GIJw
      f+ewqUzd3MGTeQxuUA5hAkBkkA65Jwhg5DrL7GFLj7m3phyPED+Uk2pP7GJ5vIFf
      QgM7yYJFHvKg/enuc2w2aAni+V8Z4DfwWeDlhPjcPyhb
      -----END RSA PRIVATE KEY-----
      */
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      // ✅ 安装依赖:npm install node-rsa
      
      // ❌ 密钥输出格式不支持 jwk、openssh
      // ❌ 不支持对私钥进行签名、加密
      // ❓ 注意:截止 2024.03,该库中公钥语法标准支持 pkcs8,但实际上不存在这种说法,具有争议,正确应该是 spki,参见:https://github.com/rzcoder/node-rsa/issues/208
      
      var NodeRSA = require("node-rsa");
      
      
      var key = new NodeRSA({
          b: 1024,  // 密钥位数,默认 2048,即模数(modulus)的位数,常见的有 512 位、1024 位、2048 位、3072 位和 4096 位
          e: 65537  // 公钥指数,默认 65537(0x10001),该值是除了 1、3、5、17、257 之外的最小素数
      });
      
      // 生成密钥,传入参数格式:语法标准-密钥类型-输出格式,即 scheme-[key_type]-[output_type]
      var publicKey = key.exportKey("pkcs1-public-pem");    // 公钥语法标准支持 pkcs1、pkcs8,输出格式支持 pem、der
      var privateKey = key.exportKey("pkcs8-private-pem");  // 私钥语法标准支持 pkcs1、pkcs8,输出格式支持 pem、der
      
      console.log("RSA 公钥(pkcs1、pem):\n\n", publicKey);
      console.log("RSA 私钥(pkcs8、pem):\n\n", privateKey);
      
      
      /*
      RSA 公钥(pkcs1、pem):
      
       -----BEGIN RSA PUBLIC KEY-----
      MIGJAoGBALBIxnoOWWhdvAzaicfo5UB2DbSEa2u9LPQl0DrZSnQduRPs/EHh0EqC
      QlBBJndqa0QuWAp5In/Q4Sjc2lcF7oB8MEzz1P+D/2M2vy1EunXD8XbMBDbyNAvg
      k6yldcT3jEP1yhZjH9JnvgC9JsBFSjC9pUsZbhFDZwY6XLvw9oF7AgMBAAE=
      -----END RSA PUBLIC KEY-----
      
      RSA 私钥(pkcs8、pem):
      
       -----BEGIN PRIVATE KEY-----
      MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALBIxnoOWWhdvAza
      icfo5UB2DbSEa2u9LPQl0DrZSnQduRPs/EHh0EqCQlBBJndqa0QuWAp5In/Q4Sjc
      2lcF7oB8MEzz1P+D/2M2vy1EunXD8XbMBDbyNAvgk6yldcT3jEP1yhZjH9JnvgC9
      JsBFSjC9pUsZbhFDZwY6XLvw9oF7AgMBAAECgYEAgfs3NZpM/HJZDVU6UIf+OfiS
      BG+7UTas5dzX2/yKNHISHIoaOm3JipbfVJOlTFnQe/Z7/kTxVjNrQhkOeSorf6Ee
      Zg64JAMOxCb3aEJ6jABZUCK5DnBkcBv3qoPI6FrwrZNcTDypUGE6zxFfxehetGlQ
      hyJ4xgddFNXg9oxoTKECQQDnpUujoYCSFITC+UDnMXCcV5LXk0wyicySL1+YeP8o
      ymz3LYUTyR0p1JoMeXdg2VpQ3BVX4QDNRGv9mS79dI+xAkEAwtFv2U3egkUacdNv
      vkWgMSVZc7YtlPdiW91wyVmAqxqFNBOVDOBXcuHcZ1o8mzPMgJVwSkjldvi73Ko5
      s5C66wJBAMVikEVqRMg1O7t38NoPwsk1xiZzmSYnTW3zeB3QXHxBoQAuhYsKgBM4
      2dtvVU3tZ4wnPPiY/bnrZ6m8cdH/FMECQAuhx6TY4mUyzQ5oym446ASnLz0aboRL
      dQL5KMfM4ULWFYfzd13Kc043sBo3qBC4OgifY5H74j+FQGo/e6x+ArsCQQCtogcc
      uKx8DHSON+lPQQfgD9A8vCtJVC7pyzzthMoUbmiGnv+VzbPkfuPaiamdVZy6j6qM
      vuQJ+AB8c5SoY5rb
      -----END PRIVATE KEY-----
      */
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      // ✅ 安装依赖:npm install jsencrypt
      
      // ❗ 如果在 Node 环境中使用,会遇到报错 window is not defined,处理方法:
      //    1.在当前 JS 文件顶部添加代码:window = global;
      //    2.在 \node_modules\jsencrypt\bin\jsencrypt.js 添加代码:window = global;
      // ❌ 不支持对私钥进行签名、加密
      // ❌ 密钥输出格式不支持 der、jwk、openssh,仅支持 pem
      // ❌ 公钥语法标准不支持 pkcs1,仅支持 spki
      // ❌ 私钥语法标准不支持 pkcs8,仅支持 pkcs1
      
      var JSEncrypt = require('jsencrypt');
      
      
      var crypt = new JSEncrypt({
          default_key_size: "1024",          // 密钥位数,默认 1024,即模数(modulus)的位数,常见的有 512 位、1024 位、2048 位、3072 位和 4096 位
          default_public_exponent: "010001"  // 公钥指数,默认 65537(0x10001),该值是除了 1、3、5、17、257 之外的最小素数
      });
      
      var publicKey = crypt.getPublicKey();    // 公钥语法标准默认 spki,输出格式默认 pem
      var privateKey = crypt.getPrivateKey();  // 私钥语法标准默认 pkcs1,输出格式默认 pem
      
      console.log("RSA 公钥(spki、pem):\n\n", publicKey);
      console.log("RSA 私钥(pkcs1、pem):\n\n", privateKey);
      
      
      /*
      RSA 公钥(spki、pem):
      
      -----BEGIN PUBLIC KEY-----
      MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGq2tRBEpDRG26JrXmBxxThGbufn
      C2yw0biiXUf3BPzPx65TQ5vgiOoOnGYWl3wIhzlACPVWW4gto+nk2elcwin9flDb
      vxtJCiBvEVqAaGb3ceiMe56xFnYs88PnDImzecguMCFmwhpbRpkLuvpF8fW4I2+M
      aa3zON2rB5A2yMAxAgMBAAE=
      -----END PUBLIC KEY-----
      RSA 私钥(pkcs1、pem):
      
      -----BEGIN RSA PRIVATE KEY-----
      MIICWgIBAAKBgGq2tRBEpDRG26JrXmBxxThGbufnC2yw0biiXUf3BPzPx65TQ5vg
      iOoOnGYWl3wIhzlACPVWW4gto+nk2elcwin9flDbvxtJCiBvEVqAaGb3ceiMe56x
      FnYs88PnDImzecguMCFmwhpbRpkLuvpF8fW4I2+Maa3zON2rB5A2yMAxAgMBAAEC
      gYBd5OTrq3nPhYk7H72qnnApU8/BvEkRGYNuMW5iI7b/utK3UAvs22Ocjb6PFNG1
      EMvqU62OMK3Y5E+VPQd/jV5I8C8n2BymrJ2MexCFow9jKneZYX5OLdRitJw+FAxL
      8OnlLHs4nRlKiWJbdZ2Y/OnlYpAmHpStmAs+2loI/AWsAQJBALNOLJYCgZcm8yOO
      cjnt+Q2gbPUWUfRha+x4oZ9jKFVk/xtYQ9GrWysYyi2IBfFkP362OrAdJHdCpjT+
      6DhA/30CQQCYW8p0mRb0WtNmqLF+W7c+8CbPQ4+YeCnADzldNZkRshg/BgOMM41P
      zVMqYFmlhHepIrno0uA6pNqrDi6Sx8nFAkBoviX1i4lATxSBlNjNVmLCvxBnK568
      b5yoCt//R+Fr4Q/VXX5goQUk69pPNsKh/LnKv5ERCDUhJeIJ2060bePRAkAUSv2P
      RCi7iTFpFgT2GI8ysdfpeU0x+KdO7ngsgwwNQFRcaJemX+NtgqKWHVkzY45wl7B9
      Y0D8bqK1b+EiKbwlAkBB1wPeHe97FJ1QaleMhjDIWLjZZiX1UZYrDbaUbmLwhzmM
      1pXmXbW1K0VxC9jcKpN7htwYvOmXuYdOsGHdG1MW
      -----END RSA PRIVATE KEY-----
      */
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      // Make sure to add code blocks to your code group

      # Golang 1.0+

      // ✅ 无需安装依赖,官方文档:https://pkg.go.dev/crypto
      // ❌ 公钥指数不支持自定义,默认 65537(0x10001),该值是除了 1、3、5、17、257 之外的最小素数
      // ❌ 密钥输出格式不支持 jwk、openssh
      // ❌ 对私钥进行签名、加密,只支持 pkcs1 标准的私钥,不支持 pkcs8 标准的私钥
      
      package main
      
      import (
          "crypto/rand"
          "crypto/rsa"
          "crypto/x509"
          "encoding/pem"
          "fmt"
      )
      
      func main() {
          rsaKey, err := rsa.GenerateKey(rand.Reader, 2048)
          if err != nil {
              fmt.Println("Generate key failed:", err)
              return
          }
      
          // 私钥输出格式 der,私钥语法标准支持 pkcs1 (MarshalPKCS1PrivateKey)、pkcs8 (MarshalPKCS8PrivateKey)
          privateKeyDER := x509.MarshalPKCS1PrivateKey(rsaKey)
        
          // 可选操作:使用密码加密私钥,注意,EncryptPEMBlock 方法正在被弃用,该方法只能加密 pkcs1 标准的私钥
          // blockType 参数指定密钥的标头,与私钥语法标准对应:pkcs1 加密对应 "RSA PRIVATE KEY"
          // alg 参数指定加密算法,参见:https://pkg.go.dev/crypto/x509#PEMCipher
          password := []byte("spiderapi")
          encryptedPrivateKeyPEMBlock, err := x509.EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", privateKeyDER, password, x509.PEMCipherAES256)
          if err != nil {
              fmt.Println("Private key encrypt failed:", err)
              return
          }
          encryptedPrivateKeyPEM := pem.EncodeToMemory(encryptedPrivateKeyPEMBlock)
        
          // 将私钥转为 pem 格式
          // Type 参数指定密钥的标头,与私钥语法标准对应:pkcs1 对应 "RSA PRIVATE KEY",pkcs8 对应 "PRIVATE KEY"
          privateKeyPEM := pem.EncodeToMemory(&pem.Block{
              Type:  "RSA PRIVATE KEY",
              Bytes: privateKeyDER,
          })
        
          // 公钥输出格式 der,公钥语法标准支持 pkcs1 (MarshalPKCS1PublicKey)、spki (MarshalPKIXPublicKey)
          publicKeyPEM, err := x509.MarshalPKIXPublicKey(&rsaKey.PublicKey)
          if err != nil {
              fmt.Println("Public key encoding failed:", err)
              return
          }
        
          // 将公钥转为 pem 格式
          // Type 参数指定密钥的标头,与公钥语法标准对应:pkcs1 对应 "RSA PUBLIC KEY",spki 对应 "PUBLIC KEY"
          publicKey := pem.EncodeToMemory(&pem.Block{
              Type:  "PUBLIC KEY",
              Bytes: publicKeyPEM,
          })
        
          fmt.Println("RSA 公钥(spki、pem):\n\n", string(publicKey))
          fmt.Println("RSA 私钥(pkcs1、pem):\n\n", string(privateKeyPEM))
          fmt.Println("RSA 加密后的私钥(pkcs1、pem、aes-256-cbc):\n\n", string(encryptedPrivateKeyPEM))
      }
      
      /*
      RSA 公钥(spki、pem):
      
      -----BEGIN PUBLIC KEY-----
      MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1P94ik8uUca0kq613hw0
      dy0i/dALloDg4I32lkk7eWV/obe2I/qEY2Nz7SmmY8VZeJUfiQuAVuOxFYI7rKPM
      4LvSvkKC5xcWho1319eyZKC1AYlXKHjQPrUXNrDwmM1racGw9NopFg/GyikhaZiT
      vsW7NM3O3HN26irQXFO0C7vypIaZtOIB9YVA9YFpBLNnINczRyekltoZqhL4j/Of
      C+VuXZOxL0wfJOML7axF4Fwt7XSir8BPJMoEc2KVFYxMMd06tfJMRzvHOEckOaob
      ZLrZjHM4YzDr32ClpgCazx7QWsBiMo3AqMuNO+LBV/VynsZPymgehIiDRGr7+S0F
      ywIDAQAB
      -----END PUBLIC KEY-----
      
      RSA 私钥(pkcs1、pem):
      
      -----BEGIN RSA PRIVATE KEY-----
      MIIEowIBAAKCAQEA1P94ik8uUca0kq613hw0dy0i/dALloDg4I32lkk7eWV/obe2
      I/qEY2Nz7SmmY8VZeJUfiQuAVuOxFYI7rKPM4LvSvkKC5xcWho1319eyZKC1AYlX
      KHjQPrUXNrDwmM1racGw9NopFg/GyikhaZiTvsW7NM3O3HN26irQXFO0C7vypIaZ
      tOIB9YVA9YFpBLNnINczRyekltoZqhL4j/OfC+VuXZOxL0wfJOML7axF4Fwt7XSi
      r8BPJMoEc2KVFYxMMd06tfJMRzvHOEckOaobZLrZjHM4YzDr32ClpgCazx7QWsBi
      Mo3AqMuNO+LBV/VynsZPymgehIiDRGr7+S0FywIDAQABAoIBAQDSQhYFwkAhLZvX
      KGwTg5gvBPmDv7mQqkxSnxEKLeRt48noI+fDAGtriSNIvFKqLogxxlNI/3eDTmTi
      rJqnw1Jdjkts0U9TO7FaxY/GHADX4OSNTbwiEZDQNgdiT6xRyoX78d3y9uCUDKLZ
      sVxwVtOSALLaX0eSytBaPEVOvrn+0Y06x/jiKhHvw1LCNc+E0lp3myrwW+6f0LCJ
      KD4dc5AWop64psKwDXP2t8bcyK5uhLjZYiSKjSi+7y8kCNmN0LimYjbjt8nvHo1J
      s24BbfE/MwrXhuV2/1ODBezPoOLBm51rzt9syHHnQBh95LPdLPr5N5r5uPvkToDu
      X5eM5ughAoGBAPxvHiyoKjWTc2cYw2exsabp2OOkKHH5BP8VBErEvTzmbzr9mKFR
      PG0ZcxLnSPux9xaoExdNd+NPnVWl5sR3ZLezGLSaeZw5RagTlkQ/YOXZ6b7mWZcE
      hpZNlvSyG3dIP63N4ONwTCpRrjyndv/sSGARrHsp4I1mv+23cQaQfvADAoGBANgB
      vUh8Uekq6SuJ2MmvX63cq5kK6BejWfEk6xFlHOTE49yzorn8yJoy1dBoO5BN1VcZ
      NUPSNt7PP0HR0BAgX5pKun/dAIs9+Y4HJPojeLkkhFgjx0FxQrQ2usIAaqAwZlpC
      rzClr7/8ZO5jeZMdfxcqE43KNrWOWGleyYQnr9yZAoGAcMPCmvhUQrKnrrplMAE0
      9vcnqClA2AkBrmFZFX1le7sEnTmD4SxE7gecXCltdOI/GqPiQ1qb37NE+Wmu+LzN
      BTLAKo2HHb6H21lEmyAkzQjXXivQgaHH7YSjlpOpqVNg/uclOvSDUbRDPV0hz5lh
      i2jZv/spEIGB41M67k/GJLkCgYAzRZZsUjYPJoRaNUoj9WC8oBiLJy+YDMoYly7E
      3j9RffqoNGt3wizLjS17XoJk6lSta+pcwtULZh4ZvXepnEWVFg/WsdqjMn6926xH
      Q4wwRh6z3So6umue4y7JRdgJVfO1kQaMgYeKBpreivYcmW/FS9OAYHND/Rm3SSyE
      FfeEYQKBgAVICBeE9LrMzoPwaTiGcRwEbx13Mo2SgzrKiwSY960Ewlu5t17197e0
      EEqJ1Y+ItIA+4j9XEMu6e1hV56Zy9rNEOyUZSB83tB1TQTzasbTDLfh0vJZmbudF
      6VTo4nST7kLzJYJe4A1SF2gLKasrbBL0Ye22PK2AuwHIWca2e+OS
      -----END RSA PRIVATE KEY-----
      
      RSA 加密后的私钥(pkcs1、pem、aes-256-cbc):
      
      -----BEGIN RSA PRIVATE KEY-----
      Proc-Type: 4,ENCRYPTED
      DEK-Info: AES-256-CBC,3a42d48c94f2f06b0354a04de8247917
      
      6rr+ZAQXJXS3zv9gZUbSp+Ft1ngcjshRrlKYcbeXaBPbWwfwE0iwG47aSJIpAvR1
      ac2NhCTyq8ATqbjrhdf4dSHGYwpLJZzdQ7X+g3FmvJpLJMglaLhM2ls+IN+ofOS+
      Bp9DwCSvdvTQEocHqTImXS98Bb6pr49FdJmQMma8pm2U73fIro8apVTDwQD/iHIB
      nEQ6+ZvUIqp+spEifYle0d1q1ADU/ZavqMt21bDhz56Ccf++6unXk+BhYVGj1WX0
      LYmZS8yRVHWDPk19i8yOCeMfZSS929JhCIsRVWYomxSVdwQP6h2iG4tU2+5mvDo1
      Pbr4BrLKjFCO3ixhbjmW+ySNoNB/dNkkNd4eaBvmUoC1A/sNz3rJQR2Kl5r9kOCi
      iVzh7hpPHTGmW9GY3PBYsIIE84HwrMpmcHHX/qWg/P5B/qAqOXQb4n8UozwuICdn
      w/i8c/k6YwOndYkIUqJjUg4KmWTdAQkyaCceBi/i4p9XgWZvq7MKQSQw0K9SeBoz
      Q7zUmJjFBtaLN/N3ckyuTeWQOZtGlVjK/rZKFy99RsMum//HX+S8XciUgs2p8A0f
      HMrIpgFg3XQSW5el4ykNdS216hEmMtUWfrGhn5D4UEDIHMRF5j9abR2T2BhKbh8m
      KcagOdBRRdKBH8JU8l3NT+tSYI+DpbMFH7X1QwfZNVlChAZblipOT9PpW4LbuZhv
      nIDU7KjodaV1JrRSOs/+9ferPKxkCXsGj3n5W/9wfbwUnChhhuYXvBVbNd48Os9m
      j5jQFVdcxQNe4UyYa7L3KaEzbp9GwX6MsUbiATH7jqEqfero50oTEznWKh4GQtrZ
      UL5QhESMEb+3X+JC1nu3aFzbvm+Y0dRjj5bi/R4wk1CAMIOWyT/iYSz+Oe9CNsVA
      gKQ5pjY4fwrLjwXVDsm52sQT99V6fVWbUXmg1iNrZ3hbLZ7sGZ0iK6ecz+x4zzMG
      m7/7Lbdb0wwGD+K5RPtDmmR9PvwCbxdfQGy8sLyUnUIB1btLRyTnPTXseuIZyFLu
      BKWTeLWhqya2h7B9iDYxQq1ySKAJaD8n6Rp+plUqJiyaO/RYcJRwun/U/GVuSfct
      YT1BytgfGqM6GL0S+RzFuaG7EYgg8vRuKwHw9rjdaIIz//cL/Y8YCJhJIhmVd7GJ
      NE5f+DXPvhhMf/12CF/rcGy6VVGnhlCHN+6dHWeodcbQVbuMJaznasqTk8NuWV75
      fZ70FmdHlJHHzTmZ/bQe6qp/1IKLYxa5v8lZEG9ER2hQ2uSjOzLt0nRc8K/HX7xA
      Fi+8mRxjsOok75QKfJHNyCXL33hxDclnGbqANUp8bE45h1F3RWnQ60QYc6/EVE9Y
      FOKqqOMrTjcIebJN4zYNUDT1OClB6VdyaJLmPtzIYDE07qwWoHdGWVQmrofR/hzL
      5+c3LY2AtxQvIyWJc7BmP6lp46KmoUcc9BLkydi5bp9XDM2OgZGjHN9pkdhqdyNH
      3zkUzf5dimvaPLHHlKtz1MNF7LTkPRJX94ATq1PDhsgX9OX0lvI10lb+MCI483Mq
      IOIIMVT9256lXj+b+q+AhxkhSg4vMLmv28/O8+QZehwcqM1CeA4qzafLGziA/6tl
      -----END RSA PRIVATE KEY-----
      */
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138

      # 解析密钥

      关于解析 RSA 密钥

      PKCS1 RSA 公钥和私钥格式的 ASN.1 (opens new window) 规范如下:

      RSAPublicKey ::= SEQUENCE {
          modulus           INTEGER,  -- n
          publicExponent    INTEGER   -- e
      }
      
      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
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17

      为了提高效率,许多流行的加密库都使用基于中国剩余定理(CRT)来优化加速解密和签名,所以 prime1、prime2 等值已预先计算并存储为私钥的一部分,如果给定一对 RSA 密钥,那么我们就可以从中解析出以下信息:

      • keySize:密钥的位数,即模数(modulus)的位数
      • modulus:模数 ,一个大素数的乘积,用于生成公钥和私钥,参见前面生成密钥中对模数的解释
      • publicExponent:公钥指数 ,参见前面生成密钥中对公钥指数的解释
      • privateExponent:私钥指数 ,参见前面生成密钥中对私钥指数的解释
      • prime1:RSA 算法中的第一个质数 ,用于生成私钥
      • prime2:RSA 算法中的第二个质数 ,用于生成私钥
      • exponent1:私钥指数模 的模反元素,即
      • exponent2:私钥指数模 的模反元素,即
      • coefficient:模反元素之间的系数,即

      【实用参考资料】

      公钥加密标准 PKCS#1 rfc3447:https://www.rfc-editor.org/rfc/rfc3447 (opens new window)
      使用中国剩余定理(CRT)来加速 RSA 算法的计算:https://www.di-mgt.com.au/crt_rsa.html (opens new window)
      维基百科 Using the Chinese remainder algorithm:https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Padding_schemes (opens new window)

      # Python 3.0+


        # ✅ 安装依赖 pip install pycryptodome,官方文档:https://pycryptodome.readthedocs.io/
        
        from Crypto.PublicKey import RSA
        
        
        # 注意 """ 之后要紧跟着密钥标头,如果换行可能会因为无法解析导致报错:ValueError: RSA key format is not supported
        # spki 标准 pem 格式的公钥
        public_key_pem = """-----BEGIN PUBLIC KEY-----
        MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl7HWuXcOH9I/Bud7dplYxHOEC
        D82fJv1WJKADhmILCxDLJLVkueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5
        jrHT8zw8InrNRwlDeCyx/Q+ETpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faN
        w6cBVKhFn+fuItSGfQIDAQAB
        -----END PUBLIC KEY-----
        """
        
        # pkcs1 标准 pem 格式的私钥
        private_key_pem = """-----BEGIN RSA PRIVATE KEY-----
        MIICXgIBAAKBgQCl7HWuXcOH9I/Bud7dplYxHOECD82fJv1WJKADhmILCxDLJLVk
        ueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5jrHT8zw8InrNRwlDeCyx/Q+E
        TpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faNw6cBVKhFn+fuItSGfQIDAQAB
        AoGBAKSmc1kmfoQJciZh1gDJsTpnV/l9ySQnwrma+pbE4cHnpzCPKtnbgfcfNNWh
        CJljGupfyvzbs1SZkCUL/B1yBR3uAbWw5G0uzJo61wYciufnQA1/lu3JyEyLeSxb
        eFOIkuI8Ce0SCPT01+6sR77EA0VtUA+0Ak7OI4EvElFPn0qBAkEA8SvKXG6suLFL
        9TjUH2B1XDwMxQFw7JOOhAyLcbNJMLgqMhHuqvTW/T4oxTQh7LbDMP977ZDnkmdt
        L8S7zAHHsQJBALAgOFkbNNH4FzBQtxyWEu6+D0ZhvhIAIoH0pDBdoIO9vKalRgWy
        vV6YsI3NujjBjz1p7g3Zb/zliA3vH9ieqo0CQQCdlOVmvBIzo/Vjx7wivF4y5DHb
        z/M/QbMPaTr8Eg+yu8MmcD0oi06mriTppgS8rTahH26UbehB6z6Wxc+Hn2ohAkEA
        r2GmOrToyBzvmmEFtiWK/MmtlDxIdMxFkHr39GGHMSiC7r6tF4eBIu2RAePWiCXW
        aSVOs+PNrFs0PAvd/mshEQJAYpxilxZI7hJT89Qne6CgPXqqZf0sFX0FeR9AJaj1
        g2c+B9GgZ+Nou4ne4WXjOVUWZuuch7yqn3XoxeQT4/xaCw==
        -----END RSA PRIVATE KEY-----
        """
        
        # 解析公钥和私钥
        public_key = RSA.importKey(public_key_pem)
        private_key = RSA.importKey(private_key_pem)
        
        # 获取模数(modulus),使用 16 进制字符串表示,从公钥和私钥中均可获取,且值是一样的
        modulus = hex(public_key.n)[2:]  # 或者 private_key.n
        
        # 计算密钥的位数,即模数(modulus)的位数,16 进制转换为位数时每个字符代表 4 位
        key_length = len(modulus) * 4
        
        # 获取公钥指数
        public_exponent = hex(public_key.e)[2:]
        
        # 获取私钥指数
        private_exponent = hex(private_key.d)[2:]
        
        # 获取私钥其他参数
        private_prime1 = hex(private_key.p)[2:]
        private_prime2 = hex(private_key.q)[2:]
        private_exponent1 = hex(private_key.d % (private_key.p - 1))[2:]
        private_exponent2 = hex(private_key.d % (private_key.q - 1))[2:]
        private_coefficient = hex(pow(private_key.q, -1, private_key.p))[2:]
        
        print("(16 进制)模数: ", modulus)                          # a5ec75ae5dc387f48fc1b9dedda656311ce1020fcd9f26fd5624a00386620b0b10cb24b564b9e0507f0508b4f10b17744b86cfb7f973587c68b3ecf3cf871575a5ecb98eb1d3f33c3c227acd470943782cb1fd0f844e94a94089af20b7f44411ed9ce815a5be35ba1285db8c061f8abbf9f68dc3a70154a8459fe7ee22d4867d
        print("(16 进制)密钥 & 模数位数: ", key_length)             # 1024
        print("(16 进制)公钥指数: ", public_exponent)               # 0x10001 (65537)
        print("(16 进制)私钥指数: ", private_exponent)              # a4a67359267e8409722661d600c9b13a6757f97dc92427c2b99afa96c4e1c1e7a7308f2ad9db81f71f34d5a10899631aea5fcafcdbb3549990250bfc1d72051dee01b5b0e46d2ecc9a3ad7061c8ae7e7400d7f96edc9c84c8b792c5b78538892e23c09ed1208f4f4d7eeac47bec403456d500fb4024ece23812f12514f9f4a81
        print("(16 进制)私钥 prime1: ", private_prime1)            # f12bca5c6eacb8b14bf538d41f60755c3c0cc50170ec938e840c8b71b34930b82a3211eeaaf4d6fd3e28c53421ecb6c330ff7bed90e792676d2fc4bbcc01c7b1
        print("(16 进制)私钥 prime2: ", private_prime2)            # b02038591b34d1f8173050b71c9612eebe0f4661be12002281f4a4305da083bdbca6a54605b2bd5e98b08dcdba38c18f3d69ee0dd96ffce5880def1fd89eaa8d
        print("(16 进制)私钥 exponent1: ", private_exponent1)      # 9d94e566bc1233a3f563c7bc22bc5e32e431dbcff33f41b30f693afc120fb2bbc326703d288b4ea6ae24e9a604bcad36a11f6e946de841eb3e96c5cf879f6a21
        print("(16 进制)私钥 exponent2: ", private_exponent2)      # af61a63ab4e8c81cef9a6105b6258afcc9ad943c4874cc45907af7f46187312882eebead17878122ed9101e3d68825d669254eb3e3cdac5b343c0bddfe6b2111
        print("(16 进制)私钥 coefficient: ", private_coefficient)  # 629c62971648ee1253f3d4277ba0a03d7aaa65fd2c157d05791f4025a8f583673e07d1a067e368bb89dee165e339551666eb9c87bcaa9f75e8c5e413e3fc5a0b
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        # ✅ 安装依赖 pip install cryptography,要求 Python 3.7+,官方文档:https:#cryptography.io/
        
        from cryptography.hazmat.primitives import serialization
        
        
        # spki 标准 pem 格式的公钥
        public_key_pem = """
        -----BEGIN PUBLIC KEY-----
        MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl7HWuXcOH9I/Bud7dplYxHOEC
        D82fJv1WJKADhmILCxDLJLVkueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5
        jrHT8zw8InrNRwlDeCyx/Q+ETpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faN
        w6cBVKhFn+fuItSGfQIDAQAB
        -----END PUBLIC KEY-----
        """
        
        # pkcs1 标准 pem 格式的私钥
        private_key_pem = """
        -----BEGIN RSA PRIVATE KEY-----
        MIICXgIBAAKBgQCl7HWuXcOH9I/Bud7dplYxHOECD82fJv1WJKADhmILCxDLJLVk
        ueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5jrHT8zw8InrNRwlDeCyx/Q+E
        TpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faNw6cBVKhFn+fuItSGfQIDAQAB
        AoGBAKSmc1kmfoQJciZh1gDJsTpnV/l9ySQnwrma+pbE4cHnpzCPKtnbgfcfNNWh
        CJljGupfyvzbs1SZkCUL/B1yBR3uAbWw5G0uzJo61wYciufnQA1/lu3JyEyLeSxb
        eFOIkuI8Ce0SCPT01+6sR77EA0VtUA+0Ak7OI4EvElFPn0qBAkEA8SvKXG6suLFL
        9TjUH2B1XDwMxQFw7JOOhAyLcbNJMLgqMhHuqvTW/T4oxTQh7LbDMP977ZDnkmdt
        L8S7zAHHsQJBALAgOFkbNNH4FzBQtxyWEu6+D0ZhvhIAIoH0pDBdoIO9vKalRgWy
        vV6YsI3NujjBjz1p7g3Zb/zliA3vH9ieqo0CQQCdlOVmvBIzo/Vjx7wivF4y5DHb
        z/M/QbMPaTr8Eg+yu8MmcD0oi06mriTppgS8rTahH26UbehB6z6Wxc+Hn2ohAkEA
        r2GmOrToyBzvmmEFtiWK/MmtlDxIdMxFkHr39GGHMSiC7r6tF4eBIu2RAePWiCXW
        aSVOs+PNrFs0PAvd/mshEQJAYpxilxZI7hJT89Qne6CgPXqqZf0sFX0FeR9AJaj1
        g2c+B9GgZ+Nou4ne4WXjOVUWZuuch7yqn3XoxeQT4/xaCw==
        -----END RSA PRIVATE KEY-----
        """
        
        # 解析公钥和私钥
        public_key = serialization.load_pem_public_key(public_key_pem.encode())
        private_key = serialization.load_pem_private_key(private_key_pem.encode(), password=None)
        
        public_numbers = public_key.public_numbers()
        private_numbers = private_key.private_numbers()
        
        # 获取模数(modulus),使用 16 进制字符串表示,从公钥和私钥中均可获取,且值是一样的
        modulus = hex(public_numbers.n)[2:]  # 或者 private_numbers.public_numbers.n
        
        # 计算密钥的位数,即模数(modulus)的位数,16 进制转换为位数时每个字符代表 4 位
        key_length = len(modulus) * 4
        
        # 获取公钥指数
        public_exponent = hex(public_numbers.e)[2:]
        
        # 获取私钥指数
        private_exponent = hex(private_numbers.d)[2:]
        
        # 获取私钥其他参数
        private_prime1 = hex(private_numbers.p)[2:]
        private_prime2 = hex(private_numbers.q)[2:]
        private_exponent1 = hex(private_numbers.dmp1)[2:]
        private_exponent2 = hex(private_numbers.dmq1)[2:]
        private_coefficient = hex(private_numbers.iqmp)[2:]
        
        print("(16 进制)模数: ", modulus)                          # a5ec75ae5dc387f48fc1b9dedda656311ce1020fcd9f26fd5624a00386620b0b10cb24b564b9e0507f0508b4f10b17744b86cfb7f973587c68b3ecf3cf871575a5ecb98eb1d3f33c3c227acd470943782cb1fd0f844e94a94089af20b7f44411ed9ce815a5be35ba1285db8c061f8abbf9f68dc3a70154a8459fe7ee22d4867d
        print("(16 进制)密钥 & 模数位数: ", key_length)             # 1024
        print("(16 进制)公钥指数: ", public_exponent)               # 0x10001 (65537)
        print("(16 进制)私钥指数: ", private_exponent)              # a4a67359267e8409722661d600c9b13a6757f97dc92427c2b99afa96c4e1c1e7a7308f2ad9db81f71f34d5a10899631aea5fcafcdbb3549990250bfc1d72051dee01b5b0e46d2ecc9a3ad7061c8ae7e7400d7f96edc9c84c8b792c5b78538892e23c09ed1208f4f4d7eeac47bec403456d500fb4024ece23812f12514f9f4a81
        print("(16 进制)私钥 prime1: ", private_prime1)            # f12bca5c6eacb8b14bf538d41f60755c3c0cc50170ec938e840c8b71b34930b82a3211eeaaf4d6fd3e28c53421ecb6c330ff7bed90e792676d2fc4bbcc01c7b1
        print("(16 进制)私钥 prime2: ", private_prime2)            # b02038591b34d1f8173050b71c9612eebe0f4661be12002281f4a4305da083bdbca6a54605b2bd5e98b08dcdba38c18f3d69ee0dd96ffce5880def1fd89eaa8d
        print("(16 进制)私钥 exponent1: ", private_exponent1)      # 9d94e566bc1233a3f563c7bc22bc5e32e431dbcff33f41b30f693afc120fb2bbc326703d288b4ea6ae24e9a604bcad36a11f6e946de841eb3e96c5cf879f6a21
        print("(16 进制)私钥 exponent2: ", private_exponent2)      # af61a63ab4e8c81cef9a6105b6258afcc9ad943c4874cc45907af7f46187312882eebead17878122ed9101e3d68825d669254eb3e3cdac5b343c0bddfe6b2111
        print("(16 进制)私钥 coefficient: ", private_coefficient)  # 629c62971648ee1253f3d4277ba0a03d7aaa65fd2c157d05791f4025a8f583673e07d1a067e368bb89dee165e339551666eb9c87bcaa9f75e8c5e413e3fc5a0b
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        # ✅ 安装依赖 pip install rsa,官方文档:https://stuvel.eu/python-rsa-doc/
        
        # ❌ 不支持解析 spki 语法标准的公钥,只支持 pkcs1
        # ❌ 不支持解析 pkcs8 语法标准的私钥,只支持 pkcs1
        
        import rsa
        
        
        # pkcs1 标准 pem 格式的公钥
        public_key_pem = """
        -----BEGIN RSA PUBLIC KEY-----
        MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
        C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
        1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
        -----END RSA PUBLIC KEY-----
        """
        
        # pkcs1 标准 pem 格式的私钥
        private_key_pem = """
        -----BEGIN RSA PRIVATE KEY-----
        MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
        lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
        MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
        AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
        r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
        vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
        UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
        SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
        KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
        cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
        PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
        +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
        NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
        -----END RSA PRIVATE KEY-----
        """
        
        # 解析公钥和私钥
        public_key = rsa.PublicKey.load_pkcs1(public_key_pem.encode(), 'PEM')
        private_key = rsa.PrivateKey.load_pkcs1(private_key_pem.encode(), 'PEM')
        
        # 获取模数(modulus),使用 16 进制字符串表示,从公钥和私钥中均可获取,且值是一样的
        modulus = hex(public_key.n)[2:]  # 或者 private_key.n
        
        # 计算密钥的位数,即模数(modulus)的位数,16 进制转换为位数时每个字符代表 4 位
        key_length = len(modulus) * 4
        
        # 获取公钥指数
        public_exponent = hex(public_key.e)[2:]
        
        # 获取私钥指数
        private_exponent = hex(private_key.d)[2:]
        
        # 获取私钥其他参数
        private_prime1 = hex(private_key.p)[2:]
        private_prime2 = hex(private_key.q)[2:]
        private_exponent1 = hex(private_key.d % (private_key.p - 1))[2:]
        private_exponent2 = hex(private_key.d % (private_key.q - 1))[2:]
        private_coefficient = hex(pow(private_key.q, -1, private_key.p))[2:]
        
        print("(16 进制)模数: ", modulus)                          # b2c0fda504952c6abcf527942e00f1468d87ab71cab8e52ec856e3fc148166480416efa7bc958f83a20b999b6dbcaf3aa12540d86469e57c105dab66acbd9b9c21b3e8c8c75b5477224f2572f264236bdd0f2de2c4327a4eaad7e8a637a2941081eb2ef7ae62ad4bbe6c3796de76bd1cef5b0b9c615d041d26f1dc6d1bea112b
        print("(16 进制)密钥 & 模数位数: ", key_length)             # 1024
        print("(16 进制)公钥指数: ", public_exponent)               # 0x10001 (65537)
        print("(16 进制)私钥指数: ", private_exponent)              # ceae569876b404a765d40fef4541d1b7c1ed1c4e761752e6c4bdb2ddc4d7d96b6b4f19cad84215ae1daf4bec6af5bfa60aad084d2bcd458a2d6220cbc19f391521a921498bc2dbde32c84646f9f609717b995b3a05d3e614ae514fd1bbc6e493a90dc50de181beb46f76e006e1c8f2f4009917d0110495259a16156d9d3c401
        print("(16 进制)私钥 prime1: ", private_prime1)            # b87cc2c8cc4da10aaf45526479f580d21dab0f5150d6baad1e5c6f8fff42a9f71e595038d97288dc061a6c24141bc7d3f8ca0ca2623e2e530dce480f17fdf647c6a9a0fd
        print("(16 进制)私钥 prime2: ", private_prime2)            # f80b479533e5579a8f53e0ba1928281df7f383e7aeb2a8143fb081ce87ed089bf5a286293d31e5d2acc1979fc84fcf17e422ee131688ed7c14ad8747
        print("(16 进制)私钥 exponent1: ", private_exponent1)      # 6ff790444bf2855db5b84de41b3ccbdd3a125aae90707245a55a967eff7e17279aecbbca74f695676bf0d7572239261359384f68b25568ca1163f3c9ed56be051be65185
        print("(16 进制)私钥 exponent2: ", private_exponent2)      # 8ed3a7e761179947156ade072abf35c273e913b60fa12e2962b71737be8b1d9ef8651a4d9ac025af16ecee8b0203faa2ae29f2dea8e635a17222adb7
        print("(16 进制)私钥 coefficient: ", private_coefficient)  # 6b46e0fb2928b01030eea323b6c551ce627fd50aa3a4c67aedfd137aadbf88d6356eaa39b3c127d47582eacca8f513f60eb7d318d9759c73e9a73d67b15f823a4c57415e
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        // Make sure to add code blocks to your code group

        # JavaScript Node.js ECMAScript 5.1+

        // ✅ 安装依赖:npm install node-forge,官方文档:https://github.com/digitalbazaar/forge
        
        // ❌ 不支持解析私钥的 prime1、prime2、exponent1、exponent2、coefficient 参数
        
        var forge = require("node-forge");
        
        // spki 标准 pem 格式的公钥
        var publicKeyPEM = `
        -----BEGIN PUBLIC KEY-----
        MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl7HWuXcOH9I/Bud7dplYxHOEC
        D82fJv1WJKADhmILCxDLJLVkueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5
        jrHT8zw8InrNRwlDeCyx/Q+ETpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faN
        w6cBVKhFn+fuItSGfQIDAQAB
        -----END PUBLIC KEY-----
        `
        
        // pkcs1 标准 pem 格式的私钥
        var privateKeyPEM = `
        -----BEGIN RSA PRIVATE KEY-----
        MIICXgIBAAKBgQCl7HWuXcOH9I/Bud7dplYxHOECD82fJv1WJKADhmILCxDLJLVk
        ueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5jrHT8zw8InrNRwlDeCyx/Q+E
        TpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faNw6cBVKhFn+fuItSGfQIDAQAB
        AoGBAKSmc1kmfoQJciZh1gDJsTpnV/l9ySQnwrma+pbE4cHnpzCPKtnbgfcfNNWh
        CJljGupfyvzbs1SZkCUL/B1yBR3uAbWw5G0uzJo61wYciufnQA1/lu3JyEyLeSxb
        eFOIkuI8Ce0SCPT01+6sR77EA0VtUA+0Ak7OI4EvElFPn0qBAkEA8SvKXG6suLFL
        9TjUH2B1XDwMxQFw7JOOhAyLcbNJMLgqMhHuqvTW/T4oxTQh7LbDMP977ZDnkmdt
        L8S7zAHHsQJBALAgOFkbNNH4FzBQtxyWEu6+D0ZhvhIAIoH0pDBdoIO9vKalRgWy
        vV6YsI3NujjBjz1p7g3Zb/zliA3vH9ieqo0CQQCdlOVmvBIzo/Vjx7wivF4y5DHb
        z/M/QbMPaTr8Eg+yu8MmcD0oi06mriTppgS8rTahH26UbehB6z6Wxc+Hn2ohAkEA
        r2GmOrToyBzvmmEFtiWK/MmtlDxIdMxFkHr39GGHMSiC7r6tF4eBIu2RAePWiCXW
        aSVOs+PNrFs0PAvd/mshEQJAYpxilxZI7hJT89Qne6CgPXqqZf0sFX0FeR9AJaj1
        g2c+B9GgZ+Nou4ne4WXjOVUWZuuch7yqn3XoxeQT4/xaCw==
        -----END RSA PRIVATE KEY-----
        `
        
        // 解析公钥和私钥
        var publicKey = forge.pki.publicKeyFromPem(publicKeyPEM);
        var privateKey = forge.pki.privateKeyFromPem(privateKeyPEM);
        
        // 获取模数(modulus),使用 16 进制字符串表示,从公钥和私钥中均可获取,且值是一样的
        var modulus = publicKey.n.toString(16); // 或者 privateKey.n.toString(16);
        
        // 计算密钥的位数,即模数(modulus)的位数,16 进制转换为位数时每个字符代表 4 位
        var keyLength = modulus.length * 4;
        
        // 获取公钥指数
        var publicExponent = publicKey.e.toString(16);
        
        // 获取私钥指数
        var privateExponent = privateKey.d.toString(16);
        
        console.log("(16 进制)模数: ", modulus);              // a5ec75ae5dc387f48fc1b9dedda656311ce1020fcd9f26fd5624a00386620b0b10cb24b564b9e0507f0508b4f10b17744b86cfb7f973587c68b3ecf3cf871575a5ecb98eb1d3f33c3c227acd470943782cb1fd0f844e94a94089af20b7f44411ed9ce815a5be35ba1285db8c061f8abbf9f68dc3a70154a8459fe7ee22d4867d
        console.log("(16 进制)密钥 & 模数位数: ", keyLength);  // 1024
        console.log("(16 进制)公钥指数: ", publicExponent);    // 0x10001 (65537)
        console.log("(16 进制)私钥指数: ", privateExponent);   // a4a67359267e8409722661d600c9b13a6757f97dc92427c2b99afa96c4e1c1e7a7308f2ad9db81f71f34d5a10899631aea5fcafcdbb3549990250bfc1d72051dee01b5b0e46d2ecc9a3ad7061c8ae7e7400d7f96edc9c84c8b792c5b78538892e23c09ed1208f4f4d7eeac47bec403456d500fb4024ece23812f12514f9f4a81
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55

        # Golang 1.0+

        package main
        
        import (
            "crypto/rsa"
            "crypto/x509"
            "encoding/pem"
            "fmt"
        )
        
        func main() {
            // spki 标准 pem 格式的公钥
            publicKeyPEM := `
        -----BEGIN PUBLIC KEY-----
        MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl7HWuXcOH9I/Bud7dplYxHOEC
        D82fJv1WJKADhmILCxDLJLVkueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5
        jrHT8zw8InrNRwlDeCyx/Q+ETpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faN
        w6cBVKhFn+fuItSGfQIDAQAB
        -----END PUBLIC KEY-----
        `
            // pkcs1 标准 pem 格式的私钥
            privateKeyPEM := `
        -----BEGIN RSA PRIVATE KEY-----
        MIICXgIBAAKBgQCl7HWuXcOH9I/Bud7dplYxHOECD82fJv1WJKADhmILCxDLJLVk
        ueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5jrHT8zw8InrNRwlDeCyx/Q+E
        TpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faNw6cBVKhFn+fuItSGfQIDAQAB
        AoGBAKSmc1kmfoQJciZh1gDJsTpnV/l9ySQnwrma+pbE4cHnpzCPKtnbgfcfNNWh
        CJljGupfyvzbs1SZkCUL/B1yBR3uAbWw5G0uzJo61wYciufnQA1/lu3JyEyLeSxb
        eFOIkuI8Ce0SCPT01+6sR77EA0VtUA+0Ak7OI4EvElFPn0qBAkEA8SvKXG6suLFL
        9TjUH2B1XDwMxQFw7JOOhAyLcbNJMLgqMhHuqvTW/T4oxTQh7LbDMP977ZDnkmdt
        L8S7zAHHsQJBALAgOFkbNNH4FzBQtxyWEu6+D0ZhvhIAIoH0pDBdoIO9vKalRgWy
        vV6YsI3NujjBjz1p7g3Zb/zliA3vH9ieqo0CQQCdlOVmvBIzo/Vjx7wivF4y5DHb
        z/M/QbMPaTr8Eg+yu8MmcD0oi06mriTppgS8rTahH26UbehB6z6Wxc+Hn2ohAkEA
        r2GmOrToyBzvmmEFtiWK/MmtlDxIdMxFkHr39GGHMSiC7r6tF4eBIu2RAePWiCXW
        aSVOs+PNrFs0PAvd/mshEQJAYpxilxZI7hJT89Qne6CgPXqqZf0sFX0FeR9AJaj1
        g2c+B9GgZ+Nou4ne4WXjOVUWZuuch7yqn3XoxeQT4/xaCw==
        -----END RSA PRIVATE KEY-----
        `
          
            // 解析公钥和私钥
            publicKeyBlock, _ := pem.Decode([]byte(publicKeyPEM))
            if publicKeyBlock == nil {
                fmt.Println("Failed to decode public key")
                return
            }
            publicKeyInterface, err := x509.ParsePKIXPublicKey(publicKeyBlock.Bytes)
            if err != nil {
                fmt.Println("Failed to parse public key:", err)
                return
            }
            publicKey := publicKeyInterface.(*rsa.PublicKey)
          
            privateBlock, _ := pem.Decode([]byte(privateKeyPEM))
            if privateBlock == nil {
                fmt.Println("Failed to decode private key")
                return
            }
            privateKey, err := x509.ParsePKCS1PrivateKey(privateBlock.Bytes)
            if err != nil {
                fmt.Println("Failed to parse private key:", err)
                return
            }
          
            // 获取模数(modulus),使用 16 进制字符串表示,从公钥和私钥中均可获取,且值是一样的
            modulus := fmt.Sprintf("%x", publicKey.N) // 或者 privateKey.N
          
            // 计算密钥的位数,即模数(modulus)的位数,16 进制转换为位数时每个字符代表 4 位
            keyLength := fmt.Sprintf("%d", publicKey.N.BitLen())
          
            // 获取公钥指数
            publicExponent := fmt.Sprintf("%x", publicKey.E)
          
            // 获取私钥指数
            privateExponent := fmt.Sprintf("%x", privateKey.D)
          
            // 获取私钥其他参数
            privatePrime1 := fmt.Sprintf("%x", privateKey.Primes[0])
            privatePrime2 := fmt.Sprintf("%x", privateKey.Primes[1])
            privateExponent1 := fmt.Sprintf("%x", privateKey.Precomputed.Dp)
            privateExponent2 := fmt.Sprintf("%x", privateKey.Precomputed.Dq)
            privateCoefficient := fmt.Sprintf("%x", privateKey.Precomputed.Qinv)
          
            fmt.Println("(16 进制)模数: ", modulus)                         // a5ec75ae5dc387f48fc1b9dedda656311ce1020fcd9f26fd5624a00386620b0b10cb24b564b9e0507f0508b4f10b17744b86cfb7f973587c68b3ecf3cf871575a5ecb98eb1d3f33c3c227acd470943782cb1fd0f844e94a94089af20b7f44411ed9ce815a5be35ba1285db8c061f8abbf9f68dc3a70154a8459fe7ee22d4867d
            fmt.Println("(16 进制)密钥 & 模数位数: ", keyLength)             // 1024
            fmt.Println("(16 进制)公钥指数: ", publicExponent)              // 0x10001 (65537)
            fmt.Println("(16 进制)私钥指数: ", privateExponent)             // a4a67359267e8409722661d600c9b13a6757f97dc92427c2b99afa96c4e1c1e7a7308f2ad9db81f71f34d5a10899631aea5fcafcdbb3549990250bfc1d72051dee01b5b0e46d2ecc9a3ad7061c8ae7e7400d7f96edc9c84c8b792c5b78538892e23c09ed1208f4f4d7eeac47bec403456d500fb4024ece23812f12514f9f4a81
            fmt.Println("(16 进制)私钥 prime1: ", privatePrime1)           // f12bca5c6eacb8b14bf538d41f60755c3c0cc50170ec938e840c8b71b34930b82a3211eeaaf4d6fd3e28c53421ecb6c330ff7bed90e792676d2fc4bbcc01c7b1
            fmt.Println("(16 进制)私钥 prime2: ", privatePrime2)           // b02038591b34d1f8173050b71c9612eebe0f4661be12002281f4a4305da083bdbca6a54605b2bd5e98b08dcdba38c18f3d69ee0dd96ffce5880def1fd89eaa8d
            fmt.Println("(16 进制)私钥 exponent1: ", privateExponent1)     // 9d94e566bc1233a3f563c7bc22bc5e32e431dbcff33f41b30f693afc120fb2bbc326703d288b4ea6ae24e9a604bcad36a11f6e946de841eb3e96c5cf879f6a21
            fmt.Println("(16 进制)私钥 exponent2: ", privateExponent2)     // af61a63ab4e8c81cef9a6105b6258afcc9ad943c4874cc45907af7f46187312882eebead17878122ed9101e3d68825d669254eb3e3cdac5b343c0bddfe6b2111
            fmt.Println("(16 进制)私钥 coefficient: ", privateCoefficient) // 629c62971648ee1253f3d4277ba0a03d7aaa65fd2c157d05791f4025a8f583673e07d1a067e368bb89dee165e339551666eb9c87bcaa9f75e8c5e413e3fc5a0b
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91

        # 转换密钥

        RSA 的公钥语法标准有:pkcs1、spki,私钥的语法标准有:pkcs1、pkcs8,已知一个语法标准的秘钥,可以将其转换成另一种语法标准的秘钥,同时秘钥最终的格式 pem、der 也是可以相互转换的。

        # Python 3.0+


          # ✅ 安装依赖 pip install pycryptodome,官方文档:https://pycryptodome.readthedocs.io/
          
          # ❌ 密钥输出格式不支持 jwk
          # ❌ 公钥不支持从 spki 标准转为 pkcs1 标准
          
          from Crypto.PublicKey import RSA
          
          
          def pkcs1_to_spki(public_key_pkcs1, output_format="PEM"):
              # 将 pkcs1 标准的公钥转换为 spki 标准,返回 pem 或者 der 格式的公钥
              public_key_pkcs1 = RSA.import_key(public_key_pkcs1)
              public_key_spki = public_key_pkcs1.export_key(format=output_format.upper())
              return public_key_spki.decode()
          
          
          def pkcs1_to_pkcs8(private_key_pkcs1, output_format="PEM"):
              # 将 pkcs1 标准的私钥转换为 pkcs8 标准,返回 pem 或者 der 格式的公钥
              private_key_pkcs1 = RSA.import_key(private_key_pkcs1)
              private_key_pkcs8 = private_key_pkcs1.export_key(format=output_format.upper(), pkcs=8)
              return private_key_pkcs8.decode()
          
          
          def pkcs8_to_pkcs1(private_key_pkcs8, output_format="PEM"):
              # 将 pkcs8 标准的私钥转换为 pkcs1 标准,返回 pem 或者 der 格式的公钥
              private_key_pkcs8 = RSA.import_key(private_key_pkcs8)
              private_key_pkcs1 = private_key_pkcs8.export_key(format=output_format.upper(), pkcs=1)
              return private_key_pkcs1.decode()
          
          
          # 注意 """ 之后要紧跟着密钥标头,如果换行可能会因为无法解析导致报错:ValueError: RSA key format is not supported
          # pkcs1 标准 pem 格式的公钥
          public_key_pkcs1_pem = """-----BEGIN RSA PUBLIC KEY-----
          MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
          C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
          1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
          -----END RSA PUBLIC KEY-----
          """
          
          # pkcs1 标准 pem 格式的私钥
          private_key_pkcs1_pem = """-----BEGIN RSA PRIVATE KEY-----
          MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
          lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
          MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
          AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
          r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
          vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
          UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
          SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
          KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
          cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
          PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
          +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
          NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
          -----END RSA PRIVATE KEY-----
          """
          
          # 转换公钥:pkcs1 => spki
          public_key_spki_pem = pkcs1_to_spki(public_key_pkcs1_pem, output_format="pem")
          
          # 转换私钥:pkcs1 => pkcs8
          private_key_pkcs8_pem = pkcs1_to_pkcs8(private_key_pkcs1_pem, output_format="pem")
          
          print("公钥转换 pkcs1 => spki:\n\n", public_key_spki_pem)
          print("\n私钥转换 pkcs1 => pkcs8:\n\n", private_key_pkcs8_pem)
          
          """
          公钥转换 pkcs1 => spki:
          
          -----BEGIN PUBLIC KEY-----
          MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCywP2lBJUsarz1J5QuAPFGjYer
          ccq45S7IVuP8FIFmSAQW76e8lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPo
          yMdbVHciTyVy8mQja90PLeLEMnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sL
          nGFdBB0m8dxtG+oRKwIDAQAB
          -----END PUBLIC KEY-----
          
          私钥转换 pkcs1 => pkcs8:
          
          -----BEGIN PRIVATE KEY-----
          MIICegIBADANBgkqhkiG9w0BAQEFAASCAmQwggJgAgEAAoGBALLA/aUElSxqvPUn
          lC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4OiC5mbbbyvOqElQNhkaeV8EF2r
          Zqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q1+imN6KUEIHrLveuYq1Lvmw3
          lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAECgYAM6uVph2tASnZdQP70VB0bfB7R
          xOdhdS5sS9st3E19lra08ZythCFa4dr0vsavW/pgqtCE0rzUWKLWIgy8GfORUhqS
          FJi8Lb3jLIRkb59glxe5lbOgXT5hSuUU/Ru8bkk6kNxQ3hgb60b3bgBuHI8vQAmR
          fQEQSVJZoWFW2dPEAQJFALh8wsjMTaEKr0VSZHn1gNIdqw9RUNa6rR5cb4//Qqn3
          HllQONlyiNwGGmwkFBvH0/jKDKJiPi5TDc5IDxf99kfGqaD9Aj0A+AtHlTPlV5qP
          U+C6GSgoHffzg+eusqgUP7CBzoftCJv1ooYpPTHl0qzBl5/IT88X5CLuExaI7XwU
          rYdHAkRv95BES/KFXbW4TeQbPMvdOhJarpBwckWlWpZ+/34XJ5rsu8p09pVna/DX
          VyI5JhNZOE9oslVoyhFj88ntVr4FG+ZRhQI9AI7Tp+dhF5lHFWreByq/NcJz6RO2
          D6EuKWK3Fze+ix2e+GUaTZrAJa8W7O6LAgP6oq4p8t6o5jWhciKttwJEa0bg+yko
          sBAw7qMjtsVRzmJ/1QqjpMZ67f0Teq2/iNY1bqo5s8En1HWC6syo9RP2DrfTGNl1
          nHPppz1nsV+COkxXQV4=
          -----END PRIVATE KEY-----
          """
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          # ✅ 安装依赖 pip install cryptography,要求 Python 3.7+,官方文档:https://cryptography.io/
          
          # ❌ 密钥输出格式不支持 jwk
          # ❌ 私钥不支持从 pkcs8 标准转为 pkcs1 标准
          
          from cryptography.hazmat.primitives import serialization
          from cryptography.hazmat.primitives.serialization import load_pem_public_key, load_pem_private_key
          
          
          def pkcs1_to_spki(public_key_pkcs1, output_format="PEM"):
              # 将 pkcs1 标准的公钥转换为 spki 标准,返回 pem 或者 der 格式的公钥
              if output_format.upper() == "DER":
                  encoding = serialization.Encoding.DER
              else:
                  encoding = serialization.Encoding.PEM
              public_key_pkcs1 = load_pem_public_key(public_key_pkcs1.encode())
              public_key_spki = public_key_pkcs1.public_bytes(
                  encoding=encoding,
                  format=serialization.PublicFormat.SubjectPublicKeyInfo
              )
              return public_key_spki.decode()
          
          
          def spki_to_pkcs1(public_key_spki, output_format="PEM"):
              # 将 spki 标准的公钥转换为 pkcs1 标准,返回 pem 或者 der 格式的公钥
              if output_format.upper() == "DER":
                  encoding = serialization.Encoding.DER
              else:
                  encoding = serialization.Encoding.PEM
              public_key_spki = load_pem_public_key(public_key_spki.encode())
              public_key_pkcs1 = public_key_spki.public_bytes(
                  encoding=encoding,
                  format=serialization.PublicFormat.PKCS1
              )
              return public_key_pkcs1.decode()
          
          
          def pkcs1_to_pkcs8(private_key_pkcs1, output_format="PEM"):
              # 将 pkcs1 标准的私钥转换为 pkcs8 标准,返回 pem 或者 der 格式的公钥
              if output_format.upper() == "DER":
                  encoding = serialization.Encoding.DER
              else:
                  encoding = serialization.Encoding.PEM
              private_key_pkcs1 = load_pem_private_key(private_key_pkcs1.encode(), password=None)  # 可选参数 password,指定私钥的密码
              private_key_pkcs8 = private_key_pkcs1.private_bytes(
                  encoding=encoding,
                  format=serialization.PrivateFormat.PKCS8,
                  encryption_algorithm=serialization.NoEncryption()  # 可选参数 encryption_algorithm,指定私钥的加密算法
              )
              return private_key_pkcs8.decode()
          
          
          # spki 标准 pem 格式的公钥
          public_key_spki_pem = """-----BEGIN PUBLIC KEY-----
          MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl7HWuXcOH9I/Bud7dplYxHOEC
          D82fJv1WJKADhmILCxDLJLVkueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5
          jrHT8zw8InrNRwlDeCyx/Q+ETpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faN
          w6cBVKhFn+fuItSGfQIDAQAB
          -----END PUBLIC KEY-----
          """
          
          # pkcs1 标准 pem 格式的私钥
          private_key_pkcs1_pem = """-----BEGIN RSA PRIVATE KEY-----
          MIICXgIBAAKBgQCl7HWuXcOH9I/Bud7dplYxHOECD82fJv1WJKADhmILCxDLJLVk
          ueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5jrHT8zw8InrNRwlDeCyx/Q+E
          TpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faNw6cBVKhFn+fuItSGfQIDAQAB
          AoGBAKSmc1kmfoQJciZh1gDJsTpnV/l9ySQnwrma+pbE4cHnpzCPKtnbgfcfNNWh
          CJljGupfyvzbs1SZkCUL/B1yBR3uAbWw5G0uzJo61wYciufnQA1/lu3JyEyLeSxb
          eFOIkuI8Ce0SCPT01+6sR77EA0VtUA+0Ak7OI4EvElFPn0qBAkEA8SvKXG6suLFL
          9TjUH2B1XDwMxQFw7JOOhAyLcbNJMLgqMhHuqvTW/T4oxTQh7LbDMP977ZDnkmdt
          L8S7zAHHsQJBALAgOFkbNNH4FzBQtxyWEu6+D0ZhvhIAIoH0pDBdoIO9vKalRgWy
          vV6YsI3NujjBjz1p7g3Zb/zliA3vH9ieqo0CQQCdlOVmvBIzo/Vjx7wivF4y5DHb
          z/M/QbMPaTr8Eg+yu8MmcD0oi06mriTppgS8rTahH26UbehB6z6Wxc+Hn2ohAkEA
          r2GmOrToyBzvmmEFtiWK/MmtlDxIdMxFkHr39GGHMSiC7r6tF4eBIu2RAePWiCXW
          aSVOs+PNrFs0PAvd/mshEQJAYpxilxZI7hJT89Qne6CgPXqqZf0sFX0FeR9AJaj1
          g2c+B9GgZ+Nou4ne4WXjOVUWZuuch7yqn3XoxeQT4/xaCw==
          -----END RSA PRIVATE KEY-----
          """
          
          # 转换公钥:spki => pkcs1
          public_key_pkcs1_pem = spki_to_pkcs1(public_key_spki_pem, output_format="pem")
          
          # 转换私钥:pkcs1 => pkcs8
          private_key_pkcs8_pem = pkcs1_to_pkcs8(private_key_pkcs1_pem, output_format="pem")
          
          print("公钥转换 spki => pkcs1:\n\n", public_key_pkcs1_pem)
          print("私钥转换 pkcs1 => pkcs8:\n\n", private_key_pkcs8_pem)
          
          """
          公钥转换 spki => pkcs1:
          
           -----BEGIN RSA PUBLIC KEY-----
          MIGJAoGBAKXsda5dw4f0j8G53t2mVjEc4QIPzZ8m/VYkoAOGYgsLEMsktWS54FB/
          BQi08QsXdEuGz7f5c1h8aLPs88+HFXWl7LmOsdPzPDwies1HCUN4LLH9D4ROlKlA
          ia8gt/REEe2c6BWlvjW6EoXbjAYfirv59o3DpwFUqEWf5+4i1IZ9AgMBAAE=
          -----END RSA PUBLIC KEY-----
          
          私钥转换 pkcs1 => pkcs8:
          
           -----BEGIN PRIVATE KEY-----
          MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKXsda5dw4f0j8G5
          3t2mVjEc4QIPzZ8m/VYkoAOGYgsLEMsktWS54FB/BQi08QsXdEuGz7f5c1h8aLPs
          88+HFXWl7LmOsdPzPDwies1HCUN4LLH9D4ROlKlAia8gt/REEe2c6BWlvjW6EoXb
          jAYfirv59o3DpwFUqEWf5+4i1IZ9AgMBAAECgYEApKZzWSZ+hAlyJmHWAMmxOmdX
          +X3JJCfCuZr6lsThweenMI8q2duB9x801aEImWMa6l/K/NuzVJmQJQv8HXIFHe4B
          tbDkbS7MmjrXBhyK5+dADX+W7cnITIt5LFt4U4iS4jwJ7RII9PTX7qxHvsQDRW1Q
          D7QCTs4jgS8SUU+fSoECQQDxK8pcbqy4sUv1ONQfYHVcPAzFAXDsk46EDItxs0kw
          uCoyEe6q9Nb9PijFNCHstsMw/3vtkOeSZ20vxLvMAcexAkEAsCA4WRs00fgXMFC3
          HJYS7r4PRmG+EgAigfSkMF2gg728pqVGBbK9Xpiwjc26OMGPPWnuDdlv/OWIDe8f
          2J6qjQJBAJ2U5Wa8EjOj9WPHvCK8XjLkMdvP8z9Bsw9pOvwSD7K7wyZwPSiLTqau
          JOmmBLytNqEfbpRt6EHrPpbFz4efaiECQQCvYaY6tOjIHO+aYQW2JYr8ya2UPEh0
          zEWQevf0YYcxKILuvq0Xh4Ei7ZEB49aIJdZpJU6z482sWzQ8C93+ayERAkBinGKX
          FkjuElPz1Cd7oKA9eqpl/SwVfQV5H0AlqPWDZz4H0aBn42i7id7hZeM5VRZm65yH
          vKqfdejF5BPj/FoL
          -----END PRIVATE KEY-----
          """
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          110
          111
          112
          113
          114
          115
          116
          // Make sure to add code blocks to your code group

          # JavaScript Node.js ECMAScript 5.1+

          // ✅ Node.js 内置 crypto 模块,无需单独安装
          
          const crypto = require("crypto");
          
          function PKCS1ToSPKI(publicKeyPkcs1, outputFormat="pem") {
              // 将 pkcs1 标准的公钥转换为 spki 标准,返回 pem 或者 der 格式的公钥
              const publicKeySpki = crypto.createPublicKey({ key: publicKeyPkcs1, type: "pkcs1" });
              return publicKeySpki.export({ type: "spki", format: outputFormat.toLowerCase() });
          }
          
          function SPKIToPKCS1(publicKeySpki, outputFormat="pem") {
              // 将 spki 标准的公钥转换为 pkcs1 标准,返回 pem 或者 der 格式的公钥
              const publicKeyPkcs1 = crypto.createPublicKey({ key: publicKeySpki, type: "spki" });
              return publicKeyPkcs1.export({ type: "pkcs1", format: outputFormat.toLowerCase() });
          }
          
          function PKCS1ToPKCS8(privateKeyPkcs1, outputFormat="pem") {
              // 将 pkcs1 标准的私钥转换为 pkcs8 标准,返回 pem 或者 der 格式的公钥
              const privateKeyPkcs8 = crypto.createPrivateKey({ key: privateKeyPkcs1, type: "pkcs1" });
              return privateKeyPkcs8.export({ type: "pkcs8", format: outputFormat.toLowerCase() });
          }
          
          function PKCS8ToPKCS1(privateKeyPkcs8, outputFormat="pem") {
              // 将 pkcs8 标准的私钥转换为 pkcs1 标准,返回 pem 或者 der 格式的公钥
              const privateKeyPkcs1 = crypto.createPrivateKey({ key: privateKeyPkcs8, type: "pkcs8" });
              return privateKeyPkcs1.export({ type: "pkcs1", format: outputFormat.toLowerCase() });
          }
          
          
          // pkcs1 标准 pem 格式的公钥
          const publicKeyPkcs1Pem = `
          -----BEGIN RSA PUBLIC KEY-----
          MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
          C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
          1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
          -----END RSA PUBLIC KEY-----
          `
          
          // pkcs1 标准 pem 格式的私钥
          const privateKeyPkcs1Pem = `
          -----BEGIN RSA PRIVATE KEY-----
          MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
          lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
          MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
          AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
          r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
          vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
          UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
          SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
          KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
          cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
          PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
          +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
          NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
          -----END RSA PRIVATE KEY-----
          `
          
          
          // 转换公钥:pkcs1 => spki
          var publicKeySpkiPem = PKCS1ToSPKI(publicKeyPkcs1Pem, "pem")
          
          // 转换私钥:pkcs1 => pkcs8
          var privateKeyPkcs8Pem = PKCS1ToPKCS8(privateKeyPkcs1Pem, "pem")
          
          console.log("公钥转换 pkcs1 => spki:\n\n", publicKeySpkiPem)
          console.log("私钥转换 pkcs1 => pkcs8:\n\n", privateKeyPkcs8Pem)
          
          
          /*
          公钥转换 pkcs1 => spki:
          
           -----BEGIN PUBLIC KEY-----
          MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCywP2lBJUsarz1J5QuAPFGjYer
          ccq45S7IVuP8FIFmSAQW76e8lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPo
          yMdbVHciTyVy8mQja90PLeLEMnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sL
          nGFdBB0m8dxtG+oRKwIDAQAB
          -----END PUBLIC KEY-----
          
          私钥转换 pkcs1 => pkcs8:
          
           -----BEGIN PRIVATE KEY-----
          MIICegIBADANBgkqhkiG9w0BAQEFAASCAmQwggJgAgEAAoGBALLA/aUElSxqvPUn
          lC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4OiC5mbbbyvOqElQNhkaeV8EF2r
          Zqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q1+imN6KUEIHrLveuYq1Lvmw3
          lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAECgYAM6uVph2tASnZdQP70VB0bfB7R
          xOdhdS5sS9st3E19lra08ZythCFa4dr0vsavW/pgqtCE0rzUWKLWIgy8GfORUhqS
          FJi8Lb3jLIRkb59glxe5lbOgXT5hSuUU/Ru8bkk6kNxQ3hgb60b3bgBuHI8vQAmR
          fQEQSVJZoWFW2dPEAQJFALh8wsjMTaEKr0VSZHn1gNIdqw9RUNa6rR5cb4//Qqn3
          HllQONlyiNwGGmwkFBvH0/jKDKJiPi5TDc5IDxf99kfGqaD9Aj0A+AtHlTPlV5qP
          U+C6GSgoHffzg+eusqgUP7CBzoftCJv1ooYpPTHl0qzBl5/IT88X5CLuExaI7XwU
          rYdHAkRv95BES/KFXbW4TeQbPMvdOhJarpBwckWlWpZ+/34XJ5rsu8p09pVna/DX
          VyI5JhNZOE9oslVoyhFj88ntVr4FG+ZRhQI9AI7Tp+dhF5lHFWreByq/NcJz6RO2
          D6EuKWK3Fze+ix2e+GUaTZrAJa8W7O6LAgP6oq4p8t6o5jWhciKttwJEa0bg+yko
          sBAw7qMjtsVRzmJ/1QqjpMZ67f0Teq2/iNY1bqo5s8En1HWC6syo9RP2DrfTGNl1
          nHPppz1nsV+COkxXQV4=
          -----END PRIVATE KEY-----
          */
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97

          # Golang 1.0+

          // ✅ 无需安装依赖,官方文档:https://pkg.go.dev/crypto
          
          package main
          
          import (
              "crypto/rsa"
              "crypto/x509"
              "encoding/pem"
              "errors"
              "fmt"
              "strings"
          )
          
          // PKCS1ToSPKI 将 pkcs1 标准的公钥转换为 spki 标准,返回 pem 或者 der 格式的公钥
          func PKCS1ToSPKI(publicKeyPkcs1, outputFormat string) ([]byte, error) {
              block, _ := pem.Decode([]byte(publicKeyPkcs1))
              if block == nil {
                  return nil, errors.New("failed to decode PEM block containing public key")
              }
              publicKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
              if err != nil {
                  return nil, err
              }
            
              publicKeySpkiBytes, err := x509.MarshalPKIXPublicKey(publicKey)
              if err != nil {
                  return nil, err
              }
            
              if strings.ToUpper(outputFormat) == "DER" {
                  return publicKeySpkiBytes, nil
              }
            
              publicKeySpki := &pem.Block{
                  Type:  "PUBLIC KEY",
                  Bytes: publicKeySpkiBytes,
              }
              return pem.EncodeToMemory(publicKeySpki), nil
          }
          
          // SPKIToPKCS1 将 SPKI 格式的公钥转换为 PKCS1 格式
          func SPKIToPKCS1(publicKeySpki, outputFormat string) ([]byte, error) {
              block, _ := pem.Decode([]byte(publicKeySpki))
              if block == nil {
                  return nil, errors.New("failed to decode PEM block containing public key")
              }
              publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
              if err != nil {
                  return nil, err
              }
            
              rsaPublicKey, ok := publicKey.(*rsa.PublicKey)
              if !ok {
                  return nil, errors.New("not an RSA public key")
              }
              publicKeyPkcs1Bytes := x509.MarshalPKCS1PublicKey(rsaPublicKey)
            
              if strings.ToUpper(outputFormat) == "DER" {
                  return publicKeyPkcs1Bytes, nil
              }
            
              publicKeyPkcs1 := &pem.Block{
                  Type:  "RSA PUBLIC KEY",
                  Bytes: publicKeyPkcs1Bytes,
              }
              return pem.EncodeToMemory(publicKeyPkcs1), nil
          }
          
          // PKCS1ToPKCS8 将 pkcs1 标准的私钥转换为 pkcs8 标准,返回 pem 或者 der 格式的公钥
          func PKCS1ToPKCS8(privateKeyPkcs1, outputFormat string) ([]byte, error) {
              block, _ := pem.Decode([]byte(privateKeyPkcs1))
              if block == nil {
                  return nil, errors.New("failed to decode PEM block containing public key")
              }
              privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
              if err != nil {
                  return nil, err
              }
            
              privateKeyPkcs8Bytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
              if err != nil {
                  return nil, err
              }
            
              if strings.ToUpper(outputFormat) == "DER" {
                  return privateKeyPkcs8Bytes, nil
              }
            
              privateKeyPkcs8 := &pem.Block{
                  Type:  "PRIVATE KEY",
                  Bytes: privateKeyPkcs8Bytes,
              }
              return pem.EncodeToMemory(privateKeyPkcs8), nil
          }
          
          // PKCS8ToPKCS1 将 pkcs8 标准的私钥转换为 pkcs1 标准,返回 pem 或者 der 格式的公钥
          func PKCS8ToPKCS1(privateKeyPkcs8, outputFormat string) ([]byte, error) {
              block, _ := pem.Decode([]byte(privateKeyPkcs8))
              if block == nil {
                  return nil, errors.New("failed to decode PEM block containing public key")
              }
              privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
              if err != nil {
                  return nil, err
              }
            
              rsaPrivateKey, ok := privateKey.(*rsa.PrivateKey)
              if !ok {
                  return nil, errors.New("not an RSA public key")
              }
              privateKeyPkcs1Bytes := x509.MarshalPKCS1PrivateKey(rsaPrivateKey)
            
              if strings.ToUpper(outputFormat) == "DER" {
                  return privateKeyPkcs1Bytes, nil
              }
            
              privateKeyPkcs1 := &pem.Block{
                  Type:  "RSA PRIVATE KEY",
                  Bytes: privateKeyPkcs1Bytes,
              }
              return pem.EncodeToMemory(privateKeyPkcs1), nil
          }
          
          func main() {
              // pkcs1 标准 pem 格式的公钥
          	  publicKeyPkcs1Pem := `
          -----BEGIN RSA PUBLIC KEY-----
          MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
          C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
          1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
          -----END RSA PUBLIC KEY-----
          `
          
              // pkcs1 标准 pem 格式的私钥
              privateKeyPkcs1Pem := `
          -----BEGIN RSA PRIVATE KEY-----
          MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
          lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
          MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
          AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
          r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
          vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
          UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
          SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
          KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
          cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
          PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
          +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
          NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
          -----END RSA PRIVATE KEY-----
          `
              // 转换公钥:pkcs1 => spki
              publicKeySpkiPem, err := PKCS1ToSPKI(publicKeyPkcs1Pem, "pem")
              if err != nil {
                  fmt.Println("Error converting public key PKCS1 to SPKI:", err)
                  return
              }
            
              // 转换私钥:pkcs1 => pkcs8
              privateKeyPkcs8Pem, err := PKCS1ToPKCS8(privateKeyPkcs1Pem, "pem")
              if err != nil {
                  fmt.Println("Error converting private key PKCS1 to PKCS8:", err)
                  return
              }
            
              fmt.Println("公钥转换 pkcs1 => spki:\n\n", string(publicKeySpkiPem))
              fmt.Println("私钥转换 pkcs1 => pkcs8:\n\n", string(privateKeyPkcs8Pem))
          }
          
          /*
          公钥转换 pkcs1 => spki:
          
           -----BEGIN PUBLIC KEY-----
          MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCywP2lBJUsarz1J5QuAPFGjYer
          ccq45S7IVuP8FIFmSAQW76e8lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPo
          yMdbVHciTyVy8mQja90PLeLEMnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sL
          nGFdBB0m8dxtG+oRKwIDAQAB
          -----END PUBLIC KEY-----
          
          私钥转换 pkcs1 => pkcs8:
          
           -----BEGIN PRIVATE KEY-----
          MIICegIBADANBgkqhkiG9w0BAQEFAASCAmQwggJgAgEAAoGBALLA/aUElSxqvPUn
          lC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4OiC5mbbbyvOqElQNhkaeV8EF2r
          Zqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q1+imN6KUEIHrLveuYq1Lvmw3
          lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAECgYAM6uVph2tASnZdQP70VB0bfB7R
          xOdhdS5sS9st3E19lra08ZythCFa4dr0vsavW/pgqtCE0rzUWKLWIgy8GfORUhqS
          FJi8Lb3jLIRkb59glxe5lbOgXT5hSuUU/Ru8bkk6kNxQ3hgb60b3bgBuHI8vQAmR
          fQEQSVJZoWFW2dPEAQJFALh8wsjMTaEKr0VSZHn1gNIdqw9RUNa6rR5cb4//Qqn3
          HllQONlyiNwGGmwkFBvH0/jKDKJiPi5TDc5IDxf99kfGqaD9Aj0A+AtHlTPlV5qP
          U+C6GSgoHffzg+eusqgUP7CBzoftCJv1ooYpPTHl0qzBl5/IT88X5CLuExaI7XwU
          rYdHAkRv95BES/KFXbW4TeQbPMvdOhJarpBwckWlWpZ+/34XJ5rsu8p09pVna/DX
          VyI5JhNZOE9oslVoyhFj88ntVr4FG+ZRhQI9AI7Tp+dhF5lHFWreByq/NcJz6RO2
          D6EuKWK3Fze+ix2e+GUaTZrAJa8W7O6LAgP6oq4p8t6o5jWhciKttwJEa0bg+yko
          sBAw7qMjtsVRzmJ/1QqjpMZ67f0Teq2/iNY1bqo5s8En1HWC6syo9RP2DrfTGNl1
          nHPppz1nsV+COkxXQV4=
          -----END PRIVATE KEY-----
          */
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          110
          111
          112
          113
          114
          115
          116
          117
          118
          119
          120
          121
          122
          123
          124
          125
          126
          127
          128
          129
          130
          131
          132
          133
          134
          135
          136
          137
          138
          139
          140
          141
          142
          143
          144
          145
          146
          147
          148
          149
          150
          151
          152
          153
          154
          155
          156
          157
          158
          159
          160
          161
          162
          163
          164
          165
          166
          167
          168
          169
          170
          171
          172
          173
          174
          175
          176
          177
          178
          179
          180
          181
          182
          183
          184
          185
          186
          187
          188
          189
          190
          191
          192
          193
          194
          195
          196
          197
          198

          # 加密解密

          关于加密解密

          在 RSA 加密解密操作中,我们需要注意的是填充方式(padding),最常见的分为以下四种:

          • RSA_NO_PADDING: 不使用填充方案;
          • RSA_PKCS1_PADDING: 最常见,使用 PKCS#1 v1.5 填充方案;
          • RSA_PKCS1_OAEP_PADDING: OAEP (Optimal asymmetric encryption padding),最优非对称加密填充,在 PKCS#1 v2 中标准化;
          • RSA_PKCS1_PSS_PADDING: PSS (Probabilistic signature scheme),概率签名方案,在 PKCS#1 v2.1 中标准化。

          【实用参考资料】

          Padding 维基百科:https://en.wikipedia.org/wiki/Padding_(cryptography) (opens new window)
          RSA Padding 维基百科:https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Padding (opens new window)
          聊聊密码学中的Padding:https://cloud.tencent.com/developer/article/1499219 (opens new window)
          PSS (Probabilistic signature scheme):https://en.wikipedia.org/wiki/Probabilistic_signature_scheme (opens new window)
          OAEP (Optimal asymmetric encryption padding):https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding (opens new window)

          # Python 3.0+


            # ✅ 安装依赖 pip install cryptography,要求 Python 3.7+,官方文档:https://cryptography.io/
            
            # ❌ padding 填充方式只支持 RSA_PKCS1_PADDING、RSA_PKCS1_OAEP_PADDING,不支持 RSA_NO_PADDING、RSA_PKCS1_PSS_PADDING
            
            
            import base64
            from cryptography.hazmat.primitives import serialization, hashes
            from cryptography.hazmat.primitives.asymmetric import padding
            
            
            def set_padding(padding_scheme):
                if padding_scheme == "RSA_PKCS1_OAEP_PADDING":
                    return padding.OAEP(
                        mgf=padding.MGF1(algorithm=hashes.SHA256()),
                        algorithm=hashes.SHA256(),
                        label=None
                    )
                elif padding_scheme == "RSA_PKCS1_PADDING":
                    return padding.PKCS1v15()
                else:
                    raise ValueError("Unsupported padding scheme")
            
            
            # pkcs1 标准 pem 格式的公钥
            public_key_pkcs1_pem = """
            -----BEGIN RSA PUBLIC KEY-----
            MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
            C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
            1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
            -----END RSA PUBLIC KEY-----
            """
            
            # pkcs1 标准 pem 格式的私钥
            private_key_pkcs1_pem = """
            -----BEGIN RSA PRIVATE KEY-----
            MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
            lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
            MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
            AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
            r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
            vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
            UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
            SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
            KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
            cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
            PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
            +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
            NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
            -----END RSA PRIVATE KEY-----
            """
            
            public_key = serialization.load_pem_public_key(public_key_pkcs1_pem.encode())
            private_key = serialization.load_pem_private_key(private_key_pkcs1_pem.encode(), password=None)
            
            data = "spiderapi.cn - 虫术"
            padding_type = set_padding("RSA_PKCS1_PADDING")
            resultEncrypted = public_key.encrypt(data.encode(), padding_type)
            resultDecrypted = private_key.decrypt(resultEncrypted, padding_type).decode()
            
            print("RSA_PKCS1_PADDING 加密结果: ", base64.b64encode(resultEncrypted).decode())
            print("RSA_PKCS1_PADDING 解密结果: ", resultDecrypted)
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            # ✅ 安装依赖 pip install pycryptodome,官方文档:https://pycryptodome.readthedocs.io/
            
            # ❌ padding 填充方式只支持 RSA_PKCS1_PADDING、RSA_PKCS1_OAEP_PADDING,不支持 RSA_NO_PADDING、RSA_PKCS1_PSS_PADDING
            
            
            import base64
            from Crypto.PublicKey import RSA
            from Crypto.Cipher import PKCS1_v1_5  # 即 RSA_PKCS1_PADDING
            from Crypto.Cipher import PKCS1_OAEP  # 即 RSA_PKCS1_OAEP_PADDING
            
            
            def rsa_decrypt(ciphertext):
                cipher = PKCS1_v1_5.new(private_key)
                decrypted = cipher.decrypt(ciphertext, None).decode()
                return decrypted
            
            
            def rsa_encrypt(plaintext):
                cipher = PKCS1_v1_5.new(public_key)
                encrypted = cipher.encrypt(plaintext.encode())
                return encrypted
            
            
            # 注意 """ 之后要紧跟着密钥标头,如果换行可能会因为无法解析导致报错:ValueError: RSA key format is not supported
            # pkcs1 标准 pem 格式的公钥
            public_key_pkcs1_pem = """-----BEGIN RSA PUBLIC KEY-----
            MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
            C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
            1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
            -----END RSA PUBLIC KEY-----
            """
            
            # pkcs1 标准 pem 格式的私钥
            private_key_pkcs1_pem = """-----BEGIN RSA PRIVATE KEY-----
            MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
            lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
            MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
            AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
            r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
            vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
            UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
            SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
            KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
            cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
            PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
            +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
            NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
            -----END RSA PRIVATE KEY-----
            """
            
            public_key = RSA.import_key(public_key_pkcs1_pem)
            private_key = RSA.import_key(private_key_pkcs1_pem)
            
            data = "spiderapi.cn - 虫术"
            resultEncrypted = rsa_encrypt(data)
            resultDecrypted = rsa_decrypt(resultEncrypted)
            
            print("RSA_PKCS1_PADDING 加密结果: ", base64.b64encode(resultEncrypted).decode())
            print("RSA_PKCS1_PADDING 解密结果: ", resultDecrypted)
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            # ✅ 安装依赖 pip install rsa,官方文档:https://stuvel.eu/python-rsa-doc/
            
            # ❌ padding 填充方式只支持 RSA_PKCS1_PADDING
            # ❌ 不支持使用 spki 语法标准的公钥和 pkcs8 语法标准的私钥
            
            
            import rsa
            import base64
            
            
            # pkcs1 标准 pem 格式的公钥
            public_key_pkcs1_pem = """
            -----BEGIN RSA PUBLIC KEY-----
            MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
            C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
            1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
            -----END RSA PUBLIC KEY-----
            """
            
            # pkcs1 标准 pem 格式的私钥
            private_key_pkcs1_pem = """
            -----BEGIN RSA PRIVATE KEY-----
            MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
            lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
            MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
            AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
            r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
            vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
            UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
            SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
            KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
            cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
            PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
            +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
            NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
            -----END RSA PRIVATE KEY-----
            """
            
            public_key = rsa.PublicKey.load_pkcs1(public_key_pkcs1_pem.encode(), "PEM")
            private_key = rsa.PrivateKey.load_pkcs1(private_key_pkcs1_pem.encode(), "PEM")
            
            data = "spiderapi.cn - 虫术"
            resultEncrypted = rsa.encrypt(data.encode(), public_key)
            resultDecrypted = rsa.decrypt(resultEncrypted, private_key)
            
            print("RSA_PKCS1_PADDING 加密结果: ", base64.b64encode(resultEncrypted).decode())
            print("RSA_PKCS1_PADDING 解密结果: ", resultDecrypted.decode())
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            # ✅ 安装依赖 pip install pycryptodome,官方文档:https://pycryptodome.readthedocs.io/
            
            # ❌ padding 填充方式只支持 RSA_PKCS1_PADDING、RSA_PKCS1_OAEP_PADDING,不支持 RSA_NO_PADDING、RSA_PKCS1_PSS_PADDING
            # 本例由雕虫小技二群粉丝提供,ID:曹晶 Eric Cao🇨🇳
            
            
            import base64
            from Crypto.PublicKey import RSA
            from Crypto.Cipher import PKCS1_v1_5  # 即 RSA_PKCS1_PADDING
            from Crypto.Cipher import PKCS1_OAEP  # 即 RSA_PKCS1_OAEP_PADDING
            
            
            # 一次 RSA 加密对明文长度是有限制,实际上,RSA 算法本身要求加密内容也就是明文长度 M 必须 0 < M < N(模数)
            # 如果要加密一个长度大于模数 N 的明文块,就需要对明文进行分块以满足要求
            # RSA_PKCS1_PADDING,每次加密的明文必须比 RSA 密钥的模长至少少 11 个字节
            # RSA_PKCS1_OAEP_PADDING,每次加密的明文必须比 RSA 密钥的模长至少少 42 个字节
            # NO_PADDING,每次加密的明文与 RSA 的密钥的模长一样,或更短
            
            
            def rsa_encrypt(plaintext):
                plaintext = plaintext.encode('utf-8')
                chunk_size = public_key.size_in_bytes() - 11  # 设置每个小段的长度,加密时要减去一个长度,PKCS1_PADDING: 至少-11, PKCS1_OAEP_PADDING: 至少-42
                chunks = [plaintext[i:i + chunk_size] for i in range(0, len(plaintext), chunk_size)]
                encrypted_chunks = [PKCS1_v1_5.new(public_key).encrypt(chunk) for chunk in chunks]
                encrypted_data = b''.join(encrypted_chunks)
                return encrypted_data
            
            
            def rsa_decrypt(ciphertext):
                chunk_size = private_key.size_in_bytes()  # 设置每个小段的长度
                chunks = [ciphertext[i:i + chunk_size] for i in range(0, len(ciphertext), chunk_size)]
                decrypted_chunks = [PKCS1_v1_5.new(private_key).decrypt(chunk, None) for chunk in chunks]
                decrypted_data = b''.join(decrypted_chunks)
                return decrypted_data.decode('utf-8')
            
            
            # 注意 """ 之后要紧跟着密钥标头,如果换行可能会因为无法解析导致报错:ValueError: RSA key format is not supported
            # pkcs1 标准 pem 格式的公钥
            public_key_pkcs1_pem = """-----BEGIN RSA PUBLIC KEY-----
            MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
            C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
            1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
            -----END RSA PUBLIC KEY-----
            """
            
            # pkcs1 标准 pem 格式的私钥
            private_key_pkcs1_pem = """-----BEGIN RSA PRIVATE KEY-----
            MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
            lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
            MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
            AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
            r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
            vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
            UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
            SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
            KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
            cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
            PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
            +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
            NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
            -----END RSA PRIVATE KEY-----
            """
            
            public_key = RSA.import_key(public_key_pkcs1_pem)
            private_key = RSA.import_key(private_key_pkcs1_pem)
            
            data = "SpiderAPI - 虫术 - 汇总各种爬虫逆向常用 API,涉及各种网络请求库,自动化框架,爬虫框架,HOOK 脚本,ADB 命令等。SpiderAPI - Insect Techniques - Summarize various commonly used reverse APIs for web crawlers, involving various network request libraries, automation frameworks, web crawling frameworks, HOOK scripts, ADB commands, etc."
            resultEncrypted = rsa_encrypt(data)
            resultDecrypted = rsa_decrypt(resultEncrypted)
            
            print("原文长度: ", len(data))
            print("RSA_PKCS1_OAEP_PADDING 加密结果: %s" % base64.b64encode(resultEncrypted).decode())
            print("RSA_PKCS1_OAEP_PADDING 解密结果: %s" % resultDecrypted)
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            62
            63
            64
            65
            66
            67
            68
            69
            70
            71
            72
            73
            // Make sure to add code blocks to your code group

            # JavaScript Node.js ECMAScript 5.1+


              // ✅ Node.js 内置 crypto 模块,无需单独安装,官方文档:https://nodejs.org/docs/latest/api/crypto.html
              
              var crypto = require("crypto");
              
              
              function rsaEncrypt(data) {
                  var bufferData = Buffer.from(data);
                  var encrypted = crypto.publicEncrypt({
                      key: publicKey,
                      // 支持 RSA_NO_PADDING、RSA_PKCS1_PADDING、RSA_PKCS1_OAEP_PADDING、RSA_PKCS1_PSS_PADDING
                      padding: crypto.constants.RSA_PKCS1_PADDING
                  }, bufferData);
                  return encrypted.toString("base64");
              }
              
              function rsaDecrypt(cipherText) {
                  var bufferData = Buffer.from(cipherText, "base64");
                  var decrypted = crypto.privateDecrypt({
                      key: privateKey,
                      // 支持 RSA_NO_PADDING、RSA_PKCS1_PADDING、RSA_PKCS1_OAEP_PADDING、RSA_PKCS1_PSS_PADDING
                      padding: crypto.constants.RSA_PKCS1_PADDING
                  }, bufferData);
                  return decrypted.toString();
              }
              
              // pkcs1 标准 pem 格式的公钥
              var publicKeyPkcs1Pem = `
              -----BEGIN RSA PUBLIC KEY-----
              MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
              C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
              1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
              -----END RSA PUBLIC KEY-----
              `
              
              // pkcs1 标准 pem 格式的私钥
              var privateKeyPkcs1Pem = `
              -----BEGIN RSA PRIVATE KEY-----
              MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
              lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
              MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
              AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
              r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
              vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
              UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
              SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
              KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
              cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
              PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
              +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
              NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
              -----END RSA PRIVATE KEY-----
              `
              
              // 将 pem 格式的密钥转换为 crypto 可以使用的对象
              var publicKey = crypto.createPublicKey(publicKeyPkcs1Pem);
              var privateKey = crypto.createPrivateKey(privateKeyPkcs1Pem);
              
              // RSA 加解密,填充方式使用 RSA_PKCS1_PADDING,其他可选 RSA_NO_PADDING、RSA_PKCS1_OAEP_PADDING、RSA_PKCS1_PSS_PADDING
              var data = "spiderapi.cn - 虫术";
              var resultEncrypted = rsaEncrypt(data);
              var resultDecrypted = rsaDecrypt(resultEncrypted);
              
              console.log("RSA_PKCS1_PADDING 加密结果: ", resultEncrypted)
              console.log("RSA_PKCS1_PADDING 解密结果: ", resultDecrypted)
              
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40
              41
              42
              43
              44
              45
              46
              47
              48
              49
              50
              51
              52
              53
              54
              55
              56
              57
              58
              59
              60
              61
              62
              63
              64
              65
              // ✅ 安装依赖:npm install node-rsa,官方文档:https://github.com/rzcoder/node-rsa
              
              // ❓ 注意:截止 2024.03,该库中公钥语法标准支持 pkcs8,但实际上不存在这种说法,具有争议,正确应该是 spki,参见:https://github.com/rzcoder/node-rsa/issues/208
              // ❌  padding 填充方式只支持 RSA_PKCS1_PADDING、RSA_PKCS1_OAEP_PADDING,不支持 RSA_NO_PADDING、RSA_PKCS1_PSS_PADDING
              
              var NodeRSA = require("node-rsa");
              
              
              // pkcs1 标准 pem 格式的公钥
              var publicKeyPkcs1Pem = `
              -----BEGIN RSA PUBLIC KEY-----
              MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
              C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
              1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
              -----END RSA PUBLIC KEY-----
              `
              
              // pkcs1 标准 pem 格式的私钥
              var privateKeyPkcs1Pem = `
              -----BEGIN RSA PRIVATE KEY-----
              MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
              lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
              MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
              AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
              r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
              vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
              UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
              SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
              KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
              cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
              PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
              +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
              NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
              -----END RSA PRIVATE KEY-----
              `
              
              var key = new NodeRSA();
              key.setOptions({ encryptionScheme: "pkcs1" });  // 设置填充模式,默认 pkcs1_oaep
              
              // 导入密钥,传入参数格式:语法标准-密钥类型-输出格式,即 scheme-[key_type]-[output_type]
              key.importKey(publicKeyPkcs1Pem, "pkcs1-public-pem");   // 公钥语法标准支持 pkcs1、pkcs8,输出格式支持 pem、der
              key.importKey(privateKeyPkcs1Pem, "pkcs1-private-pem"); // 私钥语法标准支持 pkcs1、pkcs8,输出格式支持 pem、der
              
              // RSA 加解密
              var data = "spiderapi.cn - 虫术";
              var resultEncrypted =  key.encrypt(data, "base64");
              var resultDecrypted = key.decrypt(resultEncrypted, "utf8");
              
              console.log("RSA_PKCS1_PADDING 加密结果: ", resultEncrypted)
              console.log("RSA_PKCS1_PADDING 解密结果: ", resultDecrypted)
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40
              41
              42
              43
              44
              45
              46
              47
              48
              49
              50
              // ✅ 安装依赖:npm install jsencrypt,官方文档:https://github.com/travist/jsencrypt
              
              // ❗ 如果在 Node 环境中使用,会遇到报错 window is not defined,处理方法:
              //    1.在当前 JS 文件顶部添加代码:window = global;
              //    2.在 \node_modules\jsencrypt\bin\jsencrypt.js 添加代码:window = global;
              // ❌ padding 填充方式默认为 RSA_PKCS1_PADDING,不支持其他填充方式
              
              
              var JSEncrypt = require("jsencrypt");
              
              
              // pkcs1 标准 pem 格式的公钥
              var publicKeyPkcs1Pem = `
              -----BEGIN RSA PUBLIC KEY-----
              MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
              C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
              1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
              -----END RSA PUBLIC KEY-----
              `
              
              // pkcs1 标准 pem 格式的私钥
              var privateKeyPkcs1Pem = `
              -----BEGIN RSA PRIVATE KEY-----
              MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
              lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
              MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
              AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
              r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
              vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
              UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
              SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
              KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
              cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
              PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
              +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
              NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
              -----END RSA PRIVATE KEY-----
              `
              
              var encryptor = new JSEncrypt();
              encryptor.setPublicKey(publicKeyPkcs1Pem);
              encryptor.setPrivateKey(privateKeyPkcs1Pem);
              
              // RSA 加解密,填充方式只支持 RSA_PKCS1_PADDING
              var data = "spiderapi.cn - 虫术";
              var resultEncrypted = encryptor.encrypt(data);
              var resultDecrypted = encryptor.decrypt(resultEncrypted);
              
              console.log("RSA_PKCS1_PADDING 加密结果: ", resultEncrypted)
              console.log("RSA_PKCS1_PADDING 解密结果: ", resultDecrypted)
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40
              41
              42
              43
              44
              45
              46
              47
              48
              49
              50
              // Make sure to add code blocks to your code group

              # Golang 1.0+

              // ✅ 无需安装依赖,官方文档:https://pkg.go.dev/crypto
              
              // ❌ padding 填充方式只支持 RSA_PKCS1_PADDING、RSA_PKCS1_OAEP_PADDING,不支持 RSA_NO_PADDING、RSA_PKCS1_PSS_PADDING
              
              
              package main
              
              import (
                  "crypto/rand"
                  "crypto/rsa"
                  "crypto/x509"
                  "encoding/base64"
                  "encoding/pem"
                  "fmt"
              )
              
              func main() {
              	  // pkcs1 标准 pem 格式的公钥
              	  publicKeyPkcs1Pem := `
              -----BEGIN RSA PUBLIC KEY-----
              MIGJAoGBALLA/aUElSxqvPUnlC4A8UaNh6txyrjlLshW4/wUgWZIBBbvp7yVj4Oi
              C5mbbbyvOqElQNhkaeV8EF2rZqy9m5whs+jIx1tUdyJPJXLyZCNr3Q8t4sQyek6q
              1+imN6KUEIHrLveuYq1Lvmw3lt52vRzvWwucYV0EHSbx3G0b6hErAgMBAAE=
              -----END RSA PUBLIC KEY-----
              `
              
              	  // pkcs1 标准 pem 格式的私钥
              	  privateKeyPkcs1Pem := `
              -----BEGIN RSA PRIVATE KEY-----
              MIICYAIBAAKBgQCywP2lBJUsarz1J5QuAPFGjYerccq45S7IVuP8FIFmSAQW76e8
              lY+DoguZm228rzqhJUDYZGnlfBBdq2asvZucIbPoyMdbVHciTyVy8mQja90PLeLE
              MnpOqtfopjeilBCB6y73rmKtS75sN5bedr0c71sLnGFdBB0m8dxtG+oRKwIDAQAB
              AoGADOrlaYdrQEp2XUD+9FQdG3we0cTnYXUubEvbLdxNfZa2tPGcrYQhWuHa9L7G
              r1v6YKrQhNK81Fii1iIMvBnzkVIakhSYvC294yyEZG+fYJcXuZWzoF0+YUrlFP0b
              vG5JOpDcUN4YG+tG924AbhyPL0AJkX0BEElSWaFhVtnTxAECRQC4fMLIzE2hCq9F
              UmR59YDSHasPUVDWuq0eXG+P/0Kp9x5ZUDjZcojcBhpsJBQbx9P4ygyiYj4uUw3O
              SA8X/fZHxqmg/QI9APgLR5Uz5Veaj1PguhkoKB3384PnrrKoFD+wgc6H7Qib9aKG
              KT0x5dKswZefyE/PF+Qi7hMWiO18FK2HRwJEb/eQREvyhV21uE3kGzzL3ToSWq6Q
              cHJFpVqWfv9+Fyea7LvKdPaVZ2vw11ciOSYTWThPaLJVaMoRY/PJ7Va+BRvmUYUC
              PQCO06fnYReZRxVq3gcqvzXCc+kTtg+hLilitxc3vosdnvhlGk2awCWvFuzuiwID
              +qKuKfLeqOY1oXIirbcCRGtG4PspKLAQMO6jI7bFUc5if9UKo6TGeu39E3qtv4jW
              NW6qObPBJ9R1gurMqPUT9g630xjZdZxz6ac9Z7FfgjpMV0Fe
              -----END RSA PRIVATE KEY-----
              `
              
                  publicKeyBlock, _ := pem.Decode([]byte(publicKeyPkcs1Pem))
                  if publicKeyBlock == nil {
                      panic("Failed to parse PEM block containing the public key")
                  }
                  publicKey, err := x509.ParsePKCS1PublicKey(publicKeyBlock.Bytes)
                  if err != nil {
                      panic("Failed to parse public key: " + err.Error())
                  }
                
                  privateKeyBlock, _ := pem.Decode([]byte(privateKeyPkcs1Pem))
                  if privateKeyBlock == nil {
                      panic("Failed to parse PEM block containing the private key")
                  }
                  privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
                  if err != nil {
                      panic("Failed to parse private key: " + err.Error())
                  }
                
                  data := "spiderapi.cn - 虫术"
                
                  // RSA_PKCS1_PADDING
                  resultEncrypted, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(data))
                  // RSA_PKCS1_OAEP_PADDING
                  // resultEncrypted, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, []byte(data), nil)
                  if err != nil {
                      panic("Failed to encrypt data: " + err.Error())
                  }
                
                  // RSA_PKCS1_PADDING
                  resultDecrypted, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, resultEncrypted)
                  // RSA_PKCS1_OAEP_PADDING
                  // resultDecrypted, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, resultEncrypted, nil)
                  if err != nil {
                      panic("Failed to decrypt data: " + err.Error())
                  }
                
                  fmt.Println("RSA_PKCS1_PADDING 加密结果: ", base64.StdEncoding.EncodeToString(resultEncrypted))
                  fmt.Println("RSA_PKCS1_PADDING 解密结果: ", string(resultDecrypted))
              }
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40
              41
              42
              43
              44
              45
              46
              47
              48
              49
              50
              51
              52
              53
              54
              55
              56
              57
              58
              59
              60
              61
              62
              63
              64
              65
              66
              67
              68
              69
              70
              71
              72
              73
              74
              75
              76
              77
              78
              79
              80
              81
              82
              83
              84

              # 在线工具

              • 在线 RSA 加解密 (opens new window)
              • 公私钥格式在线转换 (opens new window)
              帮助我们改善此页 (opens new window)
              上次更新: 2025/04/22, 14:38:07
              SHA
              AES

              ← SHA AES→

              ICP 备案 鄂ICP备19003281号-9丨 MPS 公网安备 鄂公网安备42280202422959丨 Theme by Vdoing Theme Vdoing丨 Tencent EdgeOne Tencent EdgeOne丨 51la 网站统计

              Copyright © 2023 - 2025 WuKong Security.丨 正在载入网站运行时间...丨
              • 跟随系统
              • 浅色模式
              • 深色模式
              • 阅读模式