C#RSA解密报System.FormatException:“The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.”
最近改进登录加密验证部分碰到个奇怪的问题。就是前台js通过RSA加密的数据提交到后台C#后,少概率界面会报上面异常。开始给测试时候还没觉得是个事,随着不停偶发出现,就觉得这应该是一个bug。为此花了半天查找这个问题。
这里先说说为什么要用RSA加密解密。因为网站的代码和js对用户是可见的,如果采用对称加密的话那么用户可以通过看js就知道怎么解密数据了。所以为了保证传输重要数据的安全性,需要非对称加密。js给后台提交的数据用服务端给js提供的公钥加密数据。提交到后台用自己私钥解密数据。服务器给js端返回的数据用js给服务器提供的公钥加密,js用自己持有的私钥解密。这样用户在网页端只能看到一个秘钥。就能保证传输的安全性。
完整示例
可以从http://web.chacuo.net/netrsakeypair/在线生成公私钥对,需要两对。一对给前端往后台提交数据加密用。一对给后台返回数据给前端用
JS端的加密解密实现
//用RSA加密数据串,后台用LIS.Core.Util.RsaUtil.RsaDecrypt解密
function RsaEncrypt(str) {
if (str == null || str == "") {
return "";
}
//公钥
var PUBLIC_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb5yca2+r71IgVGQ4ywnNW48B/
IPb14coAempgDQJA5sN6nOD9OHzsNl1gtu4x/QBwL+Y9dAvmXsQhns15YMzvLogM
eitrbsaVPpzS6ZVVeDVf8d8Z19GSCXpM5Ovi3z15Yzk2nkVaHKTWgqZD3eOIObFD
iNlvVNbiRbz6hyKeRQIDAQAB';
//使用公钥加密
var encrypt = new JSEncrypt();
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + PUBLIC_KEY + '-----END PUBLIC KEY-----');
var num = 50;
var encrypted = "";
for (var i = 0; i < str.length; i += num) {
var startIndex = i;
var endIndex = i + num;
if (endIndex > str.length) {
endIndex = str.length;
}
var one = str.substring(startIndex, endIndex);
if (one != "") {
var oneencrypted = encrypt.encrypt(one);
//补全加密数据位数,其他语言没自动补全
oneencrypted = btoa(atob(oneencrypted).padStart(128, "\0"));
if (encrypted == "") {
encrypted += oneencrypted;
}
else {
encrypted += "^" + oneencrypted;
}
}
}
return encrypted;
}
//用RSA解密数据串,后台用LIS.Core.Util.RsaUtil.RsaEncrypt加密
function RsaDecrypt(str) {
if (str == null || str == "") {
return "";
}
//私钥钥
var Private_KEY = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMPcZ7qlNJIfgL4a
sjVKOkRmq8ZfiDbk3tF/TlqfKuWNKkB73JmAhVy6Dz1bM9wictS3xWUwXeuaHJup
lqz0sXNRyRHc2OQDrg+Qh1z7tdL6RBRK8TAQGxOC0G4/eJFCHm+2HTANU0we8wmF
olWj+Zad0iGoUc7WZXo2gMENyVIZAgMBAAECgYEAkJMJHoUEITiP18Ps99kq2YLQ
GUY7TgnzT8EhHVOQXpGtNpw3Yje0OZY92ZSQ21WyXcKpOuBQ87B2nZC5YEHfGWuY
+EJlS0ax4ckj7aEUfI1PmcblwOyAZDtYXNOigaJDLyoOYgsE3xLevdDgK94+dPp7
vt5f6MC7hydL0083L4ECQQD9N67yjkQGorxl0B9bkQPUJJjWf96nwCLLizw8LbvN
VYrbvhCF86Pag4bCphIBHUn0dUjcDljVg6hxELRirNDlAkEAxgNfzpMzFOTW+3CM
Nxlu/xxFBRqd5SboGiQA970Gn9BhNKSSweLtXAcb47iWc6/feXpY5HxST8Wf+GSw
na2NJQJBAOFx6zwfd+dkilIne1O+B+ef8cfALw+xnAkW3TlDCprlV20PioyIgFDz
m07AJvWBCzAwH/90cpke0CBiXAgijxUCQCtvggymbYYfzKjLP3a2tYpwgRNli01B
A5j4XN37MQDNjQUnNKojRT3ysUN6skYeRj83f1hfjQ7Coxyxuaxc7aECQHj3Hz2w
rKEUpNoxW3TwxHHvO7uHyD0BbAU+fdmEjrfQdkgfKLzX6kSpWpohkgkncY1WqUTV
GhQweu2nxnaLM+g=';
//使用公钥加密
var decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN PRIVATE KEY-----' + Private_KEY + '-----END PRIVATE KEY-----');
var arr = str.split("^");
var decryptMsg = "";
for (var i = 0; i < arr.length; i++) {
if (arr[i] != "") {
var onedecryptMsg = decrypt.decrypt(arr[i]);
decryptMsg += onedecryptMsg;
}
}
return decryptMsg;
}
C#端的加密解密实现,由于C#需要的公钥和私钥不是通用生成的格式,所以需要转换得到
///
/// 使用RSA实现解密
///
/// 解密数据
///
public static string RsaDecrypt(string data)
{
string privateKey = "2+cnGtvq+9SIFRkOMsJzVuPAfyD29eHKAHpqYA0CQObDepzg/Th87DZdYLbuMf0AcC/mPXQL5l7EIZ7NeWDM7y6IDHora27GlT6c0umVVXg1X/HfGdfRkgl6TOTr4t89eWM5Np5FWhyk1oKmQ93jiDmxQ4jZb1TW4kW8+ocinkU= AQAB 7arj8uW6fJChvW6OrSHldXEsg2qIG0Uo92PrVvaJ8aDign979MMVkREgpTncUNg9LFX8YgVcN/uMMZqvfmcQ8w==
7N15HGqnORSKDb8bVCRnYnINzCzu0Nz9m/GGzFTuD2tS6SqxCiG81QMCPiEgoo/+X5EvN7F6TuAi8iiV6gEh5w==
Tfj70gu2c/mLZrenzXtKaY5YuUCxKKk2+HrqkdxOg1xyE7g5daKvJ6nD2REzi751y17mb04s5Bz98KQ8IS81Kw== Xew4MPdtlam6UFcePBAvWo8FP5f1nqZyfdqY6/8lYsHY35JJH05fdUu7IO275hoY8MY+JeRfLlWcJc/IGkEWsw== vzlq1Fc7ki8jqyzo3zFdKHDynwZBHZ1QtYN4f6+r2MPCiv4GIT6dLJzbXf7fOW17ieicH3QISG2knWvmRdpXJg== SbwlYZ0yGsT16FUhbKXE9PKjPj14cZQHHsftWU2jXs3B6CAoVOAXC0FjaCWOkxZpijSVeC+sOc+25isQbM2niUCsME6dKZJ5AJnjQQ08SwEu6k2Sxa9Pf7H6w5s/RfZBALBGtwxI2ti9hm04WYwQUfLIG+RkbmZK/6c5yqCGE7U= ";
//创建RSA对象并载入[私钥]
RSACryptoServiceProvider rsaPrivate = new RSACryptoServiceProvider();
rsaPrivate.FromXmlString(privateKey);
string[] arr = data.Split('^');
string ret = "";
foreach (var o in arr)
{
if (o != "")
{
//对数据进行解密
//使用Base64将string转换为byte
byte[] privateValue = rsaPrivate.Decrypt(Convert.FromBase64String(o), false);
string privateStr = Encoding.UTF8.GetString(privateValue);
ret += privateStr;
}
}
return ret;
}
///
/// 使用RSA实现加密
///
/// 加密数据
///
public static string RsaEncrypt(string data)
{
string publicKey = "w9xnuqU0kh+AvhqyNUo6RGarxl+INuTe0X9OWp8q5Y0qQHvcmYCFXLoPPVsz3CJy1LfFZTBd65ocm6mWrPSxc1HJEdzY5AOuD5CHXPu10vpEFErxMBAbE4LQbj94kUIeb7YdMA1TTB7zCYWiVaP5lp3SIahRztZlejaAwQ3JUhk= AQAB ";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(publicKey);
int num = 50;
string encrypted = "";
for (var i = 0; i < data.Length; i += num)
{
var startIndex = i;
var endIndex = i + num;
if (endIndex > data.Length - 1)
{
endIndex = data.Length;
}
string one = data.Substring(startIndex, endIndex-startIndex);
if (one != "")
{
string oneencrypted = Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(one), false));
if (encrypted == "")
{
encrypted += oneencrypted;
}
else
{
encrypted += "^" + oneencrypted;
}
}
}
return encrypted;
}
把通用公钥和私钥格式转换为C#需要格式的逻辑如下:
///
/// 把通用的RSA私钥转换成C#需要的
///
///
///
public static string RSAPrivateKey2DotNet(string privateKey)
{
var data = Convert.FromBase64String(privateKey);
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
return string.Format("{0} {1} {2}
{3}
{4} {5} {6} {7} ",Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
}
///
/// 把通用的RSA公钥转换为C#需要的
///
///
///
public static string RSAPublicKey2DotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("{0} {1} ",Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
}
1.最先怀疑是不是js提交到后台串被截断了或者转义了,通过在前端和后台写日志发现提交的串没变。
2.然后怀疑是不是我写的加密切割有问题,因为RSA加密结果长度不得大于秘钥长度,所以我50一切割了,我把切割调整后发现也是不行。
3.然后我就用js循环1万次往C#提交解密,发现失败概率确实不低,基本几百次就有失败的,因此把怀疑点放到是不是失败时候串不完整了。为此查了很久资料,资料说RSA加密串按理应该等于秘钥长度。正常语言解密就是按这个约定实现的。但是jsencrypt.js的加密逻辑如果加密串长度不够秘钥串长度没有自动做补全,但是他自己的解密算法尝试做了补全。所以他自己加密的串解密不会报错,但是C#这些没自动补全的语言就报错。所以解决方式有两个:
1.jsencrypt.js加密后补全加密串。
2.其他语言解密方法尝试补全加密串后再解密。
JS修改部分:
//加密数据
var oneencrypted = encrypt.encrypt(one);
//补全加密数据位数,其他语言没自动补全
oneencrypted = btoa(atob(oneencrypted).padStart(128, "\0"));
C#补全加密串方法
///
/// 补全密文
///
/// 密文
/// 秘钥长度
/// 补全后的密文
private static string CorrectionCiphertext(string strCiphertext, int keySize = 1024)
{
int ciphertextLength = keySize / 8;
byte[] data = Convert.FromBase64String(strCiphertext);
var newData = new List<byte>(data);
while (newData.Count < ciphertextLength)
{
newData.Insert(0, 0x00);
}
return Convert.ToBase64String(newData.ToArray());
}
以上就是碰到的jsencrypt.js加密后台解密的坑,顺带把通用RSA秘钥转换为C#需要的秘钥一起梳理一下分享给小伙伴。
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
namespace ConsoleApp2
{
///
/// 可以通过http://web.chacuo.net/netrsakeypair/在线生成rsa秘钥对
///
///
///
///
/*
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb5yca2+r71IgVGQ4ywnNW48B/
IPb14coAempgDQJA5sN6nOD9OHzsNl1gtu4x/QBwL+Y9dAvmXsQhns15YMzvLogM
eitrbsaVPpzS6ZVVeDVf8d8Z19GSCXpM5Ovi3z15Yzk2nkVaHKTWgqZD3eOIObFD
iNlvVNbiRbz6hyKeRQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANvnJxrb6vvUiBUZ
DjLCc1bjwH8g9vXhygB6amANAkDmw3qc4P04fOw2XWC27jH9AHAv5j10C+ZexCGe
zXlgzO8uiAx6K2tuxpU+nNLplVV4NV/x3xnX0ZIJekzk6+LfPXljOTaeRVocpNaC
pkPd44g5sUOI2W9U1uJFvPqHIp5FAgMBAAECgYBJvCVhnTIaxPXoVSFspcT08qM+
PXhxlAcex+1ZTaNezcHoIChU4BcLQWNoJY6TFmmKNJV4L6w5z7bmKxBszaeJQKww
Tp0pknkAmeNBDTxLAS7qTZLFr09/sfrDmz9F9kEAsEa3DEja2L2GbThZjBBR8sgb
5GRuZkr/pznKoIYTtQJBAO2q4/LlunyQob1ujq0h5XVxLINqiBtFKPdj61b2ifGg
4oJ/e/TDFZERIKU53FDYPSxV/GIFXDf7jDGar35nEPMCQQDs3Xkcaqc5FIoNvxtU
JGdicg3MLO7Q3P2b8YbMVO4Pa1LpKrEKIbzVAwI+ISCij/5fkS83sXpO4CLyKJXq
ASHnAkBN+PvSC7Zz+Ytmt6fNe0ppjli5QLEoqTb4euqR3E6DXHITuDl1oq8nqcPZ
ETOLvnXLXuZvTizkHP3wpDwhLzUrAkBd7Dgw922VqbpQVx48EC9ajwU/l/WepnJ9
2pjr/yViwdjfkkkfTl91S7sg7bvmGhjwxj4l5F8uVZwlz8gaQRazAkEAvzlq1Fc7
ki8jqyzo3zFdKHDynwZBHZ1QtYN4f6+r2MPCiv4GIT6dLJzbXf7fOW17ieicH3QI
SG2knWvmRdpXJg==
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD3Ge6pTSSH4C+GrI1SjpEZqvG
X4g25N7Rf05anyrljSpAe9yZgIVcug89WzPcInLUt8VlMF3rmhybqZas9LFzUckR
3NjkA64PkIdc+7XS+kQUSvEwEBsTgtBuP3iRQh5vth0wDVNMHvMJhaJVo/mWndIh
qFHO1mV6NoDBDclSGQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMPcZ7qlNJIfgL4a
sjVKOkRmq8ZfiDbk3tF/TlqfKuWNKkB73JmAhVy6Dz1bM9wictS3xWUwXeuaHJup
lqz0sXNRyRHc2OQDrg+Qh1z7tdL6RBRK8TAQGxOC0G4/eJFCHm+2HTANU0we8wmF
olWj+Zad0iGoUc7WZXo2gMENyVIZAgMBAAECgYEAkJMJHoUEITiP18Ps99kq2YLQ
GUY7TgnzT8EhHVOQXpGtNpw3Yje0OZY92ZSQ21WyXcKpOuBQ87B2nZC5YEHfGWuY
+EJlS0ax4ckj7aEUfI1PmcblwOyAZDtYXNOigaJDLyoOYgsE3xLevdDgK94+dPp7
vt5f6MC7hydL0083L4ECQQD9N67yjkQGorxl0B9bkQPUJJjWf96nwCLLizw8LbvN
VYrbvhCF86Pag4bCphIBHUn0dUjcDljVg6hxELRirNDlAkEAxgNfzpMzFOTW+3CM
Nxlu/xxFBRqd5SboGiQA970Gn9BhNKSSweLtXAcb47iWc6/feXpY5HxST8Wf+GSw
na2NJQJBAOFx6zwfd+dkilIne1O+B+ef8cfALw+xnAkW3TlDCprlV20PioyIgFDz
m07AJvWBCzAwH/90cpke0CBiXAgijxUCQCtvggymbYYfzKjLP3a2tYpwgRNli01B
A5j4XN37MQDNjQUnNKojRT3ysUN6skYeRj83f1hfjQ7Coxyxuaxc7aECQHj3Hz2w
rKEUpNoxW3TwxHHvO7uHyD0BbAU+fdmEjrfQdkgfKLzX6kSpWpohkgkncY1WqUTV
GhQweu2nxnaLM+g=
-----END PRIVATE KEY-----
*/
class Program
{
static void Main(string[] args)
{
string pra1 = RSAPrivateKey2DotNet("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANvnJxrb6vvUiBUZDjLCc1bjwH8g9vXhygB6amANAkDmw3qc4P04fOw2XWC27jH9AHAv5j10C+ZexCGezXlgzO8uiAx6K2tuxpU+nNLplVV4NV/x3xnX0ZIJekzk6+LfPXljOTaeRVocpNaCpkPd44g5sUOI2W9U1uJFvPqHIp5FAgMBAAECgYBJvCVhnTIaxPXoVSFspcT08qM+PXhxlAcex+1ZTaNezcHoIChU4BcLQWNoJY6TFmmKNJV4L6w5z7bmKxBszaeJQKwwTp0pknkAmeNBDTxLAS7qTZLFr09/sfrDmz9F9kEAsEa3DEja2L2GbThZjBBR8sgb5GRuZkr/pznKoIYTtQJBAO2q4/LlunyQob1ujq0h5XVxLINqiBtFKPdj61b2ifGg4oJ/e/TDFZERIKU53FDYPSxV/GIFXDf7jDGar35nEPMCQQDs3Xkcaqc5FIoNvxtUJGdicg3MLO7Q3P2b8YbMVO4Pa1LpKrEKIbzVAwI+ISCij/5fkS83sXpO4CLyKJXqASHnAkBN+PvSC7Zz+Ytmt6fNe0ppjli5QLEoqTb4euqR3E6DXHITuDl1oq8nqcPZETOLvnXLXuZvTizkHP3wpDwhLzUrAkBd7Dgw922VqbpQVx48EC9ajwU/l/WepnJ92pjr/yViwdjfkkkfTl91S7sg7bvmGhjwxj4l5F8uVZwlz8gaQRazAkEAvzlq1Fc7ki8jqyzo3zFdKHDynwZBHZ1QtYN4f6+r2MPCiv4GIT6dLJzbXf7fOW17ieicH3QISG2knWvmRdpXJg==");
Console.WriteLine("私钥1:"+ pra1);
string pra2 = RSAPrivateKey2DotNet("MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMPcZ7qlNJIfgL4asjVKOkRmq8ZfiDbk3tF/TlqfKuWNKkB73JmAhVy6Dz1bM9wictS3xWUwXeuaHJuplqz0sXNRyRHc2OQDrg+Qh1z7tdL6RBRK8TAQGxOC0G4/eJFCHm+2HTANU0we8wmFolWj+Zad0iGoUc7WZXo2gMENyVIZAgMBAAECgYEAkJMJHoUEITiP18Ps99kq2YLQGUY7TgnzT8EhHVOQXpGtNpw3Yje0OZY92ZSQ21WyXcKpOuBQ87B2nZC5YEHfGWuY+EJlS0ax4ckj7aEUfI1PmcblwOyAZDtYXNOigaJDLyoOYgsE3xLevdDgK94+dPp7vt5f6MC7hydL0083L4ECQQD9N67yjkQGorxl0B9bkQPUJJjWf96nwCLLizw8LbvNVYrbvhCF86Pag4bCphIBHUn0dUjcDljVg6hxELRirNDlAkEAxgNfzpMzFOTW+3CMNxlu/xxFBRqd5SboGiQA970Gn9BhNKSSweLtXAcb47iWc6/feXpY5HxST8Wf+GSwna2NJQJBAOFx6zwfd+dkilIne1O+B+ef8cfALw+xnAkW3TlDCprlV20PioyIgFDzm07AJvWBCzAwH/90cpke0CBiXAgijxUCQCtvggymbYYfzKjLP3a2tYpwgRNli01BA5j4XN37MQDNjQUnNKojRT3ysUN6skYeRj83f1hfjQ7Coxyxuaxc7aECQHj3Hz2wrKEUpNoxW3TwxHHvO7uHyD0BbAU+fdmEjrfQdkgfKLzX6kSpWpohkgkncY1WqUTVGhQweu2nxnaLM+g=");
Console.WriteLine("私钥2:" + pra2);
string pub1 = RSAPublicKey2DotNet("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb5yca2+r71IgVGQ4ywnNW48B/IPb14coAempgDQJA5sN6nOD9OHzsNl1gtu4x/QBwL+Y9dAvmXsQhns15YMzvLogMeitrbsaVPpzS6ZVVeDVf8d8Z19GSCXpM5Ovi3z15Yzk2nkVaHKTWgqZD3eOIObFDiNlvVNbiRbz6hyKeRQIDAQAB");
Console.WriteLine("公钥1:" + pub1);
string pub2 = RSAPublicKey2DotNet("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD3Ge6pTSSH4C+GrI1SjpEZqvGX4g25N7Rf05anyrljSpAe9yZgIVcug89WzPcInLUt8VlMF3rmhybqZas9LFzUckR3NjkA64PkIdc+7XS+kQUSvEwEBsTgtBuP3iRQh5vth0wDVNMHvMJhaJVo/mWndIhqFHO1mV6NoDBDclSGQIDAQAB");
Console.WriteLine("公钥2:" + pub2);
//RsaDecrypt(CorrectionCiphertext("VtHQdECGRBOezGyx7LI0Q/BV2bHT2TbUzGmZBB3jxYZfgQCY+W557CxRw/hwemp80Xqg8sufOkvh6ERvwP7Vdout2B8KoFa9QesIos1qEOhPgJzKZQ7cKVDKi6Fa5QO6tXdmZhfKf3dZekGK7wUW/toiFkZDbQPU2Q381CcV3A==^en5GZwC8KPd6ggkDUm4UfBFspZjahym6tPFOw6O5PnLR/feO3ECUKg3sZ4p4HSXv92n1oKQDxQb3iEXR6vWfK2uoW2zFbJFDJdkyP4Ko2dT5MLMt7b86qkqRtpxW0GhL3Am6PInXAz5snKB3piDcqmlGgwcuHMoi0h5fiDGLq6I="));
}
///
/// 补全密文
///
/// 密文
/// 秘钥长度
/// 补全后的密文
private static string CorrectionCiphertext(string strCiphertext, int keySize = 1024)
{
int ciphertextLength = keySize / 8;
byte[] data = Convert.FromBase64String(strCiphertext);
var newData = new List<byte>(data);
while (newData.Count < ciphertextLength)
{
newData.Insert(0, 0x00);
}
return Convert.ToBase64String(newData.ToArray());
}
/// 使用RSA实现解密
///
/// 解密数据
///
public static string RsaDecrypt(string data)
{
string privateKey = "1ooE0EBfhxKwbk01nMxnEI9JW+4k6nHXKNqlFcbzfVUNwn+VmFJ/vUihJTLOSQG+38q0YlW2UEyg1SOWjb/ORzHpJq2197UZU3rs5ZMsyc2MyQPqojZ0HN/Q64YcQLt0I50IGp5UcguNKeS/bLbL3IyndtIJkqQhD3t2NA1zhJk= AQAB /lQJmrlmztI9hZejIJOyWpCKhc7D23w4g19gLEC0+H5NsxyaNtrooEP/wp6bUijblO8ZEyVHewS56sBdkLoBJQ==
1/MHBe5zZ7GOoJhezCKOJISUBmWyWt1jUPA+l9XqoJSGeer4oyNLIqkjSPVqueDO4kq3DldLuON2HkodCNp9ZQ==
IRspYOWvd06wyXoStwPi3J0iGwbuQdzqslcw+rG1nP87+AvKG0flri8L1Pa2ezxsUPfKyM46fs3/sYo248cCrQ== aypswtHJrZzcxe+3o6BGX/L3LpGLSDJzlfgTZ/A9poDul1Q3HWZnZAUBwLQhyaq5oG0pmNFTf6ZJuNBYxkr/TQ== XUrOs7JuMKPbPAA9diRgJG8aQoguxDw69+8RCjF3ySoHkzUeFtfqB8pTUew0Gq55FVlvRgmagpxG2aFvDB89vw== YgbUZjdTrssqVGvw+EEpQpbGBTxOH9V+Y0tsLQQn03eefuV+/AeOGHXsM6wAN7mVdnoPa/MQB6bLwjetnf0rCePxrrOuZGmndxuP51DzTo/M+9YRJg+yDI6uON1aZyLnZb2ecGqUoYbbn+VxAEs7yliiLozzD/A9/FMyx50bJZE= ";
//创建RSA对象并载入[私钥]
RSACryptoServiceProvider rsaPrivate = new RSACryptoServiceProvider();
rsaPrivate.FromXmlString(privateKey);
string[] arr = data.Split('^');
string ret = "";
foreach (var o in arr)
{
if (o != "")
{
//对数据进行解密
//使用Base64将string转换为byte
byte[] privateValue = rsaPrivate.Decrypt(Convert.FromBase64String(o), false);
string privateStr = Encoding.UTF8.GetString(privateValue);
ret += privateStr;
}
}
return ret;
}
///
/// 把通用的RSA私钥转换成C#需要的
///
///
///
public static string RSAPrivateKey2DotNet(string privateKey)
{
var data = Convert.FromBase64String(privateKey);
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
return string.Format("{0} {1} {2}
{3}
{4} {5} {6} {7} ",Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
}
///
/// 把通用的RSA公钥转换为C#需要的
///
///
///
public static string RSAPublicKey2DotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("{0} {1} ",Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
}
}
}