内容提要
本文介绍了一个C#实现的RSA加解密工具类EncryptUtils,支持PEM格式密钥。由于RSA单次加密长度有限,采用分段处理:加密每段最多117字节,解密每段最多256字节,循环处理并拼接结果,密文以Base64字符串返回,或还原为UTF-8明文。
延伸解读
分段加密的必要性
RSA加密算法对单次加密的数据长度有严格限制,通常不能超过密钥模长减去填充所需字节数。本文中,作者将加密分段大小设为117字节,解密分段设为256字节,这对应于1024位密钥的典型限制。如果不进行分段,直接加密超过限制的数据会抛出异常。因此,分段处理是使用RSA加密较长内容时的必要步骤。
实现细节与注意事项
代码使用RSACryptoServiceProvider并调用ImportFromPem方法导入PEM格式密钥,这要求.NET版本支持该方法(如.NET 5+)。加密时使用rsa.Encrypt(buffer, false),其中false表示不使用OAEP填充,即采用PKCS#1 v1.5填充。解密时对应使用rsa.Decrypt(buffer, false)。分段循环中,每次处理固定大小的块,最后一块可能小于该大小,代码通过条件判断正确处理。
性能与内存考量
作者在代码中预先为List<byte>设置了容量45000,这可以避免在添加大量数据时频繁扩容,提升性能。但容量值应根据实际数据量调整,过大可能浪费内存。此外,分段加密和解密涉及多次RSA运算,对于大文件可能较慢,建议仅用于加密小数据(如密钥、令牌)或结合对称加密使用。
Q&A
C#中如何实现RSA分段加密?
使用RSACryptoServiceProvider,导入PEM公钥,将明文按UTF-8编码后分段,每段最多117字节,循环调用Encrypt方法加密每段,最后将密文拼接并转为Base64字符串返回。
RSA解密时每段最大长度是多少?
解密时每段最大长度为256字节。
为什么RSA加密需要分段处理?
因为RSA单次加密的数据长度有限,不能直接加密任意长度的数据,所以需要分段处理。
EncryptUtils类支持哪种密钥格式?
支持PEM格式的密钥。
RSA加密后的密文以什么形式返回?
加密后的密文以Base64字符串形式返回。
RSA解密后如何得到原始明文?
解密后,将得到的字节数组按UTF-8编码转换为字符串,即还原为原始明文。