您的位置:首页 > 编程语言 > ASP

ASP.NET(C#)-JAVA对接RSA加密签名-第一章

2018-03-02 16:49 766 查看
        前一章为大家提供了一些关于RSA的基础知识,以及本系列文章所使用的资料。然而对于有基础或者迫切需要解决方案的读者而言,代码如何实现才是更重要的,本章节将讲解如何使用代码并借助BouncyCastle.Crypto.dll动态链接库实现与java互通RSA操作。

生成一对PEM格式秘钥 /// <summary>
/// 生成pem格式秘钥对
/// </summary>
/// <param name="publicKey">返回公钥</param>
/// <param name="privateKey">返回私钥</param>
public static void RSA_GetKeyForPEM(out string publicKey, out string privateKey)
{
RsaKeyPairGenerator rsaservice = new RsaKeyPairGenerator();
rsaservice.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
AsymmetricCipherKeyPair rsakeyservice = rsaservice.GenerateKeyPair();
//写私钥部分
TextWriter textwriterPrivateKey = new StringWriter();
PemWriter pemwriterPrivateKey = new PemWriter(textwriterPrivateKey);
pemwriterPrivateKey.WriteObject(rsakeyservice.Private);
pemwriterPrivateKey.Writer.Flush();
//写公钥部分
TextWriter textwriterPublicKey = new StringWriter();
PemWriter pemwriterPublicKey = new PemWriter(textwriterPublicKey);
pemwriterPublicKey.WriteObject(rsakeyservice.Public);
pemwriterPublicKey.Writer.Flush();

privateKey = textwriterPrivateKey.ToString();
publicKey = textwriterPublicKey.ToString();
}

使用公钥私钥进行解密(参数模拟Java)
        很多C#的小伙伴并不懂Java的一些语法,使用这样的代码,只需要照着对方提供的Java Dom填写加密(签名)参数即可(这里脑补了一个小伙伴与客户对接,并且对方只能提供一个Java Dom的情景)
    1.公钥加密(默认无填充,因为网上问这个的人很多)

         /// <summary>
        /// RSA公钥加密(Chsarp)
        /// </summary>
        /// <param name="publicKey">公钥(XML格式)</param>
        /// <param name="content">加密内容</param>
        /// <param name="encoding">编码</param>
        /// <param name="rsaencryptType">填充算法枚举</param>
        /// <returns></returns>
        public static string RSA_CsharpEncryptWithPublicKey(string publicKey, string content, Encoding encoding, RSAEncryptType rsaencryptType = RSAEncryptType.Pkcs1)
        {
            try
            {
                using (RSACryptoServiceProvider rsaservice = new RSACryptoServiceProvider())
                {
                    rsaservice.FromXmlString(publicKey);
                    encoding = encoding ?? Encoding.UTF8;
                    var bytes = rsaservice.Encrypt(encoding.GetBytes(content), GetRSAEncryptType(rsaencryptType));
                    return Convert.ToBase64String(bytes);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

    2.私钥解密        /// <summary>
/// RSA私钥解密(Java)
/// </summary>
/// <param name="publicKey">私钥(需为String串格式)</param>
/// <param name="content">解密内容</param>
/// <param name="encoding">编码(与java中保持一致即可)</param>
/// <param name="RSAPadding">填充算法(与java中保持一致即可)</param>
/// <returns></returns>
public static string RSA_JavaDecryptWithPrivateKey(string privateKey, string content, string encoding = "utf-8", string RSAPadding = "RSA/ECB/NoPadding")
{
try
{
RsaPrivateCrtKeyParameters rsaKeyParameters = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
IBufferedCipher cipher = CipherUtilities.GetCipher(RSAPadding);
cipher.Init(false, rsaKeyParameters);
var bytes = Convert.FromBase64String(content);
var resultBytes = cipher.DoFinal(bytes);
return Encoding.GetEncoding(encoding).GetString(resultBytes);
}
catch (Exception ex)
{
throw ex;
}
}

    3.私钥加密        /// <summary>
/// RSA私钥加密(Java)
/// </summary>
/// <param name="privateKey">私钥(需为String串格式)</param>
/// <param name="content">加密内容</param>
/// <param name="encoding">编码(与java中保持一致即可)</param>
/// <param name="RSAPadding">填充算法(与java中保持一致即可)</param>
/// <returns></returns>
public static string RSA_JavaEncryptWithPrivateKey(string privateKey, string content, string encoding = "utf-8", string RSAPadding = "RSA/ECB/NoPadding")
{
try
{
RsaPrivateCrtKeyParameters rsaKeyParameters = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
IBufferedCipher cipher = CipherUtilities.GetCipher(RSAPadding);
cipher.Init(true, rsaKeyParameters);
var bytes = Encoding.GetEncoding(encoding).GetBytes(content);
var resultBytes = cipher.DoFinal(bytes);
return Convert.ToBase64String(resultBytes);
}
catch (Exception ex)
{
throw ex;
}
}

    4.公钥解密           /// <summary>
/// RSA公钥解密(Java)
/// </summary>
/// <param name="publicKey">公钥(需为String串格式)</param>
/// <param name="content">解密内容</param>
/// <param name="encoding">编码(与java中保持一致即可)</param>
/// <param name="RSAPadding">填充算法(与java中保持一致即可)</param>
/// <returns></returns>
public static string RSA_JavaDecryptWithPublicKey(string publicKey, string content, string encoding = "utf-8", string RSAPadding = "RSA/ECB/NoPadding")
{
try
{
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
IBufferedCipher cipher = CipherUtilities.GetCipher(RSAPadding);
cipher.Init(false, rsaKeyParameters);
var bytes = Convert.FromBase64String(content);
var resultBytes = cipher.DoFinal(bytes);
return Encoding.GetEncoding(encoding).GetString(resultBytes);
}
catch (Exception ex)
{
throw ex;
}
}
关于是用公钥加密还是私钥加密,似乎是有个争论的,有意思的是,有人还专门分析了,大家工作累了可以看看:
https://www.zhihu.com/question/25912483

RSA签名操作(参数模拟Java)

实话说,我就是因为下面代码中的MD5withRSA这几个字才决定写这篇博客的,当时对接一个项目,对方公司提供的.NET Dom无法运行,问对方技术人员,他说了那句我久久回味的话:我不会.NET......        /// <summary>
/// RSA私钥签名(Java)
/// </summary>
/// <param name="privateKey">私钥(string格式)</param>
/// <param name="content">签名原文</param>
/// <param name="encoding">编码类型(与java中保持一致即可)</param>
/// <param name="RSAEncryptType">加密类型(与java中保持一致即可)</param>
/// <returns></returns>
public static string RSA_JavaSign(string privateKey, string content, string encoding = "utf-8", string RSAEncryptType = "MD5withRSA")
{
try
{
RsaPrivateCrtKeyParameters rsaKeyParameters = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
ISigner signer = SignerUtilities.GetSigner(RSAEncryptType);
signer.Init(true, rsaKeyParameters);
var bytes = Encoding.GetEncoding(encoding).GetBytes(content);
signer.BlockUpdate(bytes, 0, bytes.Length);
byte[] signature = signer.GenerateSignature();
return Convert.ToBase64String(signature);
}
catch (Exception ex)
{
throw ex;
}
}

        /// <summary>
/// RSA公钥验证签名(Java)
/// </summary>
/// <param name="publicKey">公钥(string格式)</param>
/// <param name="content">签名原文</param>
/// <param name="signature">签名结果</param>
/// <param name="encoding">编码类型(与java中保持一致即可)</param>
/// <param name="RSAEncryptType">加密类型(与java中保持一致即可)</param>
/// <returns></returns>
public static bool RSA_JavaVerify(string publicKey,string content,string signature, string encoding = "utf-8", string RSAEncryptType = "MD5withRSA")
{
try
{
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
ISigner signer = SignerUtilities.GetSigner(RSAEncryptType);
signer.Init(false, rsaKeyParameters);
var signatureBytes = Convert.FromBase64String(signature);
var bytes = Encoding.GetEncoding(encoding).GetBytes(content);
signer.BlockUpdate(bytes, 0, bytes.Length);
return signer.VerifySignature(signatureBytes);
}
catch (Exception ex)
{
throw ex;
}
}
关于借助BouncyCastle.Crypto.dll进行RSA加密(签名)的内容就讲到这,也许在函数的注释上回出现一些错误,但是代码层面上应该不会有大问题了,可以在博客下面留言,博主注意留言评论并做出相应调整的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: