Skip to content

Commit

Permalink
add: rsa convert key python algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
TRHX committed Mar 14, 2024
1 parent 0f321ad commit 42ccef7
Showing 1 changed file with 241 additions and 19 deletions.
260 changes: 241 additions & 19 deletions docs/03.辅助查询/04.加密算法/07.rsa.md
Original file line number Diff line number Diff line change
Expand Up @@ -1072,100 +1072,322 @@ g2c+B9GgZ+Nou4ne4WXjOVUWZuuch7yqn3XoxeQT4/xaCw==
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="转换密钥 1️⃣" active>
```python
# ✅ 安装依赖 pip install pycryptodome,官方文档:https://pycryptodome.readthedocs.io/

# ❌ 密钥输出格式不支持 jwk
# ❌ 公钥不支持从 spki 标准转为 pkcs1 标准

from Crypto.PublicKey import RSA


def pkcs1_to_spki(public_key_pkcs1, output_format="DER"):
# 将 pkcs1 标准的公钥转换为 spki 标准,返回 der 或者 pem 格式的公钥
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="DER"):
# 将 pkcs1 标准的私钥转换为 pkcs8 标准,返回 der 或者 pem 格式的公钥
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="DER"):
# 将 pkcs8 标准的私钥转换为 pkcs1 标准,返回 der 或者 pem 格式的公钥
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-----
"""

```
</code-block>

<code-block title="纯源码">
<code-block title="转换密钥 2️⃣">
```python
# ✅ 安装依赖 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="DER"):
# 将 pkcs1 标准的公钥转换为 spki 标准,返回 der 或者 pem 格式的公钥
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="DER"):
# 将 spki 标准的公钥转换为 pkcs1 标准,返回 der 或者 pem 格式的公钥
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.SubjectPublicKeyInfo
)
return public_key_pkcs1.decode()


def pkcs1_to_pkcs8(private_key_pkcs1, output_format="DER"):
# 将 pkcs1 标准的私钥转换为 pkcs8 标准,返回 der 或者 pem 格式的公钥
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 PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl7HWuXcOH9I/Bud7dplYxHOEC
D82fJv1WJKADhmILCxDLJLVkueBQfwUItPELF3RLhs+3+XNYfGiz7PPPhxV1pey5
jrHT8zw8InrNRwlDeCyx/Q+ETpSpQImvILf0RBHtnOgVpb41uhKF24wGH4q7+faN
w6cBVKhFn+fuItSGfQIDAQAB
-----END 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-----
"""

```
</code-block>
</code-group>

### JavaScript <Badge text="Node.js"/> <Badge text="ECMAScript 5.1+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="转换密钥 1️⃣" active>
</code-block>

<code-block title="纯源码">
<code-block title="转换密钥 2️⃣">
</code-block>
</code-group>

### Golang <Badge text="1.0+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="转换密钥 1️⃣" active>
</code-block>

<code-block title="纯源码">
<code-block title="转换密钥 2️⃣">
</code-block>
</code-group>

## 加密/解密
## 加密解密
### Python <Badge text="3.0+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="加密解密 1️⃣" active>
</code-block>

<code-block title="纯源码">
<code-block title="加密解密 2️⃣">
</code-block>
</code-group>

### JavaScript <Badge text="Node.js"/> <Badge text="ECMAScript 5.1+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="加密解密 1️⃣" active>
</code-block>

<code-block title="纯源码">
<code-block title="加密解密 2️⃣">
</code-block>
</code-group>

### Golang <Badge text="1.0+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="加密解密 1️⃣" active>
</code-block>

<code-block title="纯源码">
<code-block title="加密解密 2️⃣">
</code-block>
</code-group>

## 签名/验签
## 签名验签
### Python <Badge text="3.0+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="签名验签 1️⃣" active>
</code-block>

<code-block title="纯源码">
<code-block title="签名验签 2️⃣">
</code-block>
</code-group>

### JavaScript <Badge text="Node.js"/> <Badge text="ECMAScript 5.1+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="签名验签 1️⃣" active>
</code-block>
</code-group>

### Golang <Badge text="1.0+"/>
<br/>

<code-group>
<code-block title="依赖库" active>
<code-block title="签名验签 1️⃣" active>
</code-block>

<code-block title="纯源码">
<code-block title="签名验签 2️⃣">
</code-block>
</code-group>

## 主要特征

## 在线工具

- [在线 RSA 加解密](http://tools.jb51.net/password/rsa_encode)
- [公私钥格式在线转换](https://www.ssleye.com/ssltool/pkcs.html)

## 常见问题

0 comments on commit 42ccef7

Please sign in to comment.