练习:RSA 加密 / 解密
在本练习中,你将使用 RSA 公钥密码系统加密和解密消息。
使用 RSA-OAEP 加密消息
给定一条文本消息和一个 RSA 公钥(PEM 格式)。编写程序,使用 RSA-OAEP 加密方案(RSA + PKCS#1 OAEP 填充)加密消息。
输入:
输出:
- 以十六进制字符串打印加密消息。
使用你选择的编程语言编写代码。
输入示例:
Secret message
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMYhCcGpfoebriBbFaUMMwH3B5t7udir
ODJehnQTPlWLf9SVfQdx0v9ATJ2Rs5kQjdJ/wZYunMBVq6/FhgPZexsCAwEAAQ==
-----END PUBLIC KEY-----
上述输入使用一个 512 位 RSA 公钥和一条较短的明文消息,该消息在 OAEP 填充后仍能容纳在密钥长度限制内。
输出示例(对应上述输入):
218dd78c5e14b4d58efd10575b521db46c0caa5c699134abf18bbeeac170cfe446e25d0d82257082539e4ccd3e0aa8bffc1b07d2bde9e635a7b9b7fc6cf4c266
注意:由于 OAEP 填充算法引入了随机性,上述输出应当每次执行都不相同。
使用 RSA-OAEP 解密消息
给定一段使用 RSA-OAEP 加密的密文(十六进制字符串)和一个 RSA 私钥(PEM 格式)。编写程序,使用 RSA-OAEP 加密方案(RSA + PKCS#1 OAEP 填充)解密消息。
输入:
输出:
- 以明文形式打印解密后的消息
- 出现问题时打印
Decryption failed!
使用你选择的编程语言编写代码。
输入示例:
218dd78c5e14b4d58efd10575b521db46c0caa5c699134abf18bbeeac170cfe446e25d0d82257082539e4ccd3e0aa8bffc1b07d2bde9e635a7b9b7fc6cf4c266
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAMYhCcGpfoebriBbFaUMMwH3B5t7udirODJehnQTPlWLf9SVfQdx
0v9ATJ2Rs5kQjdJ/wZYunMBVq6/FhgPZexsCAwEAAQJAbNSzBkTzMswqHq3Juupz
jk3CSP7ye/i5Grnfgx0a7WOGpVrEDQNo0iihEf5pRAfaazEdfJX2Tj+auuv06392
kQIhAOeJahRwOt8cYroLZzHHf7LWQglRaTbtKShqmbLdBZMzAiEA2xADyA3xGXcl
txN0DOfSycwFyqkdlfsuyAwKibPteHkCIQDJ1P6UzHR1UwA434HYYejOU3mDN+V4
zOoI4kwTIBohAwIgLrqv09EFiUUdSnxf2RDqqhlXcu+4W/IE/K904AL9uSECICeT
tkAnJHB7k6fvox6ErJV53w06bUF1jGw8yHuaCcHX
-----END RSA PRIVATE KEY-----
上述输入使用一个 512 位 RSA 私钥和一段长度相同的加密密文。
输出示例(对应上述输入):
Secret message
另一个输入示例(错误的 512 位私钥):
218dd78c5e14b4d58efd10575b521db46c0caa5c699134abf18bbeeac170cfe446e25d0d82257082539e4ccd3e0aa8bffc1b07d2bde9e635a7b9b7fc6cf4c266
-----BEGIN RSA PRIVATE KEY-----
MIIBOQIBAAJBAJd0kbrC4AxpcqBgWVPpb8IoI/kdQkF1twrfQtoMkHgB71vpY6Sg
68CUA7Ejq/dbAHlvFdXqwEK9vXH3kFpc8pcCAwEAAQJAaFrlXm2Pun2dgWthoTOi
0YCe6LKESF43dMJIab1mfYiltrSpGaoTXLvHR+NaAgqcr9KAH24Mi05ttUBcWRsI
QQIhAOLTSyeDZnq5rqdwBlU8p6USpeImRhWRNcCHA/QLxcaPAiEAqu+O1p1YB3Mp
GKgB9PvZE3TZqmlgtEFmSMYinF3g13kCIF9FjpCXMYkkysZLWG2e32+HaKOXneJb
Lq+iRjfQZg7jAiBcm6D1YRV6I8gWFZ/JzFBVHC95BdJgljYGI2JI+QuBcQIgLJjH
IPctSCUtukz+7fdeOdw/0FINcUGvnQyuEK34UxE=
-----END RSA PRIVATE KEY-----
相应的输出应为:
Decryption failed!
请注意,RSA-OAEP 填充算法内置校验和,可以检测错误的解密尝试,但它并不是认证加密方案。
* 使用 RSA-KEM 实现混合加密 / 解密
编写一个程序,使用 RSA-KEM 混合加密方案和 AES 对称加密(可自行选择分组模式,例如 GCM 或 CTR)加密一条大型消息(大于 RSA 密钥长度,例如 PDF 文档)。
提示:
- 首先查看此示例:https://github.com/digitalbazaar/forge#rsakem。
- 请注意,某些语言很难找到 RSA-KEM 实现,因此你可以跳过此练习,或使用其他混合加密方案(例如 RSA + AES + HMAC)。
输入:
- 要加密的消息
- RSA 公钥(PEM 格式)
输出:
- 加密后的密文(十六进制字符串)
- AES 密码的随机 IV 盐值(十六进制字符串)
- 加密消息的认证标签 / MAC(十六进制字符串)
- AES 算法的封装秘密密钥(十六进制字符串)
编写一个程序,使用 RSA-KEM 混合加密方案和 AES 对称加密(可自行选择分组模式,例如 GCM 或 CTR),解密由上一练习生成的给定加密消息。
输入:
- 加密后的密文(十六进制字符串)
- AES 密码的随机 IV 盐值(十六进制字符串)
- 加密消息的认证标签 / MAC(十六进制字符串)
- AES 算法的封装秘密密钥(十六进制字符串)
输出:
- 解密后的原始明文消息
- 如果消息解密失败(例如密码错误),则打印
Decryption failed!