@@ -11,6 +11,139 @@ namespace GameFrameX.Foundation.Encryption;
1111/// </summary>
1212public sealed class RsaHelper
1313{
14+ /// <summary>
15+ /// 使用公钥加密数据(支持Base64格式公钥)
16+ /// </summary>
17+ /// <remarks>
18+ /// 本方法支持以下两种公钥格式:
19+ /// 1. SubjectPublicKeyInfo(PKCS#8)格式
20+ /// 2. RSAPublicKey(PKCS#1)格式
21+ /// 当数据长度超过密钥长度限制时,自动采用分块加密。
22+ /// 加密后的结果采用Base64编码返回,便于网络传输和存储。
23+ /// </remarks>
24+ /// <param name="publicKey">Base64 格式的公钥字符串,支持 PKCS#1 与 PKCS#8 两种编码</param>
25+ /// <param name="content">待加密的明文字符串,将使用 UTF-8 编码转换为字节数组</param>
26+ /// <returns>Base64 格式的加密结果,可直接用于网络传输或持久化存储</returns>
27+ /// <exception cref="ArgumentException">当 publicKey 或 content 为 null 或空字符串时抛出</exception>
28+ /// <exception cref="CryptographicException">当公钥格式非法或加密过程失败时抛出</exception>
29+ public static string EncryptBase64 ( string publicKey , string content )
30+ {
31+ ArgumentException . ThrowIfNullOrEmpty ( publicKey , nameof ( publicKey ) ) ;
32+ ArgumentException . ThrowIfNullOrEmpty ( content , nameof ( content ) ) ;
33+
34+ using var rsa = RSA . Create ( ) ;
35+ try
36+ {
37+ // 导入公钥
38+ // 注意:这里假设公钥是 PKCS#8 或 SubjectPublicKeyInfo 格式
39+ rsa . ImportSubjectPublicKeyInfo ( Convert . FromBase64String ( publicKey ) , out _ ) ;
40+
41+ // 将内容转换为字节数组
42+ var dataToEncrypt = Encoding . UTF8 . GetBytes ( content ) ;
43+
44+ // 计算最大加密块大小 (KeySize / 8 - 11 for PKCS1)
45+ // 1024位密钥 -> 128字节 -> max 117字节
46+ int bufferSize = ( rsa . KeySize / 8 ) - 11 ;
47+
48+ // 使用内存流存储加密后的数据
49+ using var outputStream = new MemoryStream ( ) ;
50+
51+ int offset = 0 ;
52+ while ( offset < dataToEncrypt . Length )
53+ {
54+ int currentBlockSize = Math . Min ( bufferSize , dataToEncrypt . Length - offset ) ;
55+ var chunk = new byte [ currentBlockSize ] ;
56+ Array . Copy ( dataToEncrypt , offset , chunk , 0 , currentBlockSize ) ;
57+
58+ var encryptedChunk = rsa . Encrypt ( chunk , RSAEncryptionPadding . Pkcs1 ) ;
59+ outputStream . Write ( encryptedChunk , 0 , encryptedChunk . Length ) ;
60+
61+ offset += currentBlockSize ;
62+ }
63+
64+ return Convert . ToBase64String ( outputStream . ToArray ( ) ) ;
65+ }
66+ catch ( CryptographicException ex )
67+ {
68+ // 如果导入失败,尝试作为 RSAPublicKey (PKCS#1) 导入
69+ rsa . ImportRSAPublicKey ( Convert . FromBase64String ( publicKey ) , out _ ) ;
70+ var dataToEncrypt = Encoding . UTF8 . GetBytes ( content ) ;
71+
72+ int bufferSize = ( rsa . KeySize / 8 ) - 11 ;
73+ using var outputStream = new MemoryStream ( ) ;
74+
75+ int offset = 0 ;
76+ while ( offset < dataToEncrypt . Length )
77+ {
78+ int currentBlockSize = Math . Min ( bufferSize , dataToEncrypt . Length - offset ) ;
79+ var chunk = new byte [ currentBlockSize ] ;
80+ Array . Copy ( dataToEncrypt , offset , chunk , 0 , currentBlockSize ) ;
81+
82+ var encryptedChunk = rsa . Encrypt ( chunk , RSAEncryptionPadding . Pkcs1 ) ;
83+ outputStream . Write ( encryptedChunk , 0 , encryptedChunk . Length ) ;
84+
85+ offset += currentBlockSize ;
86+ }
87+
88+ return Convert . ToBase64String ( outputStream . ToArray ( ) ) ;
89+ }
90+ }
91+
92+ /// <summary>
93+ /// 使用私钥解密数据(支持Base64格式私钥)
94+ /// </summary>
95+ /// <remarks>
96+ /// 本方法支持以下两种私钥格式:
97+ /// 1. PKCS#8 格式私钥
98+ /// 2. PKCS#1 格式私钥
99+ /// 当密文长度超过密钥长度时,自动采用分块解密。
100+ /// 输入的密文需为Base64编码,解密后返回明文字符串。
101+ /// </remarks>
102+ /// <param name="privateKey">Base64 格式的私钥字符串,支持 PKCS#1 与 PKCS#8 两种编码</param>
103+ /// <param name="content">Base64 格式的加密内容,需与 EncryptBase64 方法生成的格式保持一致</param>
104+ /// <returns>解密后的明文字符串,使用 UTF-8 编码还原</returns>
105+ /// <exception cref="ArgumentException">当 privateKey 或 content 为 null 或空字符串时抛出</exception>
106+ /// <exception cref="FormatException">当 content 不是合法的 Base64 字符串时抛出</exception>
107+ /// <exception cref="CryptographicException">当私钥格式非法或解密过程失败时抛出</exception>
108+ public static string DecryptBase64 ( string privateKey , string content )
109+ {
110+ ArgumentException . ThrowIfNullOrEmpty ( privateKey , nameof ( privateKey ) ) ;
111+ ArgumentException . ThrowIfNullOrEmpty ( content , nameof ( content ) ) ;
112+
113+ using var rsa = RSA . Create ( ) ;
114+ try
115+ {
116+ // 尝试导入 PKCS#8 格式私钥
117+ rsa . ImportPkcs8PrivateKey ( Convert . FromBase64String ( privateKey ) , out _ ) ;
118+ }
119+ catch ( CryptographicException )
120+ {
121+ // 尝试导入 PKCS#1 格式私钥
122+ rsa . ImportRSAPrivateKey ( Convert . FromBase64String ( privateKey ) , out _ ) ;
123+ }
124+
125+ var dataToDecrypt = Convert . FromBase64String ( content ) ;
126+
127+ // RSA 解密块大小等于密钥长度(字节)
128+ int bufferSize = rsa . KeySize / 8 ;
129+ using var outputStream = new MemoryStream ( ) ;
130+
131+ int offset = 0 ;
132+ while ( offset < dataToDecrypt . Length )
133+ {
134+ int currentBlockSize = Math . Min ( bufferSize , dataToDecrypt . Length - offset ) ;
135+ var chunk = new byte [ currentBlockSize ] ;
136+ Array . Copy ( dataToDecrypt , offset , chunk , 0 , currentBlockSize ) ;
137+
138+ var decryptedChunk = rsa . Decrypt ( chunk , RSAEncryptionPadding . Pkcs1 ) ;
139+ outputStream . Write ( decryptedChunk , 0 , decryptedChunk . Length ) ;
140+
141+ offset += currentBlockSize ;
142+ }
143+
144+ return Encoding . UTF8 . GetString ( outputStream . ToArray ( ) ) ;
145+ }
146+
14147 /// <summary>
15148 /// RSA算法提供程序实例
16149 /// </summary>
0 commit comments