C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之C#

前言

C#有自己的一套生成密钥、加解密的库,但是跟其他文互通比较费劲,经过一翻比较后,笔者选择了BouncyCastle这套库,而这套库的缺点是文档很少,只能参考Java的代码才把需求的功能实现。笔者下面提供的代码是经过多语言环境验证,可以与其他语言互通。

  1. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之前言
  2. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之C#
  3. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之Golang
  4. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之Python
  5. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之Java(Android)

代码

Des对称加密工具类

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace lhtzbj12.Encryption
{
    /// 
    /// Des对称加密工具类
    /// 
    public class DesHelper
    {
        /// 
        /// 加密
        /// 
        /// 待加密的数据
        /// 加/解密key 8位
        /// 偏移向量 8位
        /// 密码模式
        /// 填充方式
        /// 
        public static string Encrypt(string data, string key, string iv, CipherMode model = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
        {
            byte[] _KeyByte = null;
            if (!string.IsNullOrWhiteSpace(key))
            {
                _KeyByte = Encoding.UTF8.GetBytes(key);
            }

            byte[] _IVByte = null;
            if (!string.IsNullOrWhiteSpace(iv))
            {
                _IVByte = Encoding.UTF8.GetBytes(iv);
            }

            var sa = new DESCryptoServiceProvider();
            sa.Mode = model;
            sa.Padding = padding;           
            var ct = sa.CreateEncryptor(_KeyByte, _IVByte);

            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            byte[] byt = Encoding.UTF8.GetBytes(data);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return Convert.ToBase64String(ms.ToArray());
        }
        /// 
        /// 解密
        /// 
        /// 加密生成的Base64密文
        /// 加/解密key 8位
        /// 偏移向量 8位
        /// 密码模式
        /// 填充方式
        /// 
        public static string Decrypt(string encData, string key, string iv, CipherMode model = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
        {
            byte[] _KeyByte = null;
            if (!string.IsNullOrWhiteSpace(key))
            {
                _KeyByte = Encoding.UTF8.GetBytes(key);
            }

            byte[] _IVByte = null;
            if (!string.IsNullOrWhiteSpace(iv))
            {
                _IVByte = Encoding.UTF8.GetBytes(iv);
            }

            using (ICryptoTransform ct = new DESCryptoServiceProvider()
            { Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }.CreateDecryptor(_KeyByte, _IVByte))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write))
                    {
                        byte[] byt = Convert.FromBase64String(encData);
                        try
                        {
                            cs.Write(byt, 0, byt.Length);
                            cs.FlushFinalBlock();
                            cs.Close();
                        }
                        catch (Exception)
                        {
                            return string.Empty;
                        }
                    }
                    return Encoding.UTF8.GetString(ms.ToArray());
                }
            }
        }
    }
}

Rsa密钥对生成、加载(读取)工具类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System.IO;
using System.Text.RegularExpressions;

namespace lhtzbj12.Encryption
{
    /// 
    /// Rsa密钥对生成工具
    /// 
    public class RsaKeyHelper
    {
        public static void GenKey(out string publicKey, out string privateKey, out string privateKeyPk8)
        {
            publicKey = string.Empty;
            privateKey = string.Empty;
            privateKeyPk8 = string.Empty;
            try
            {
                //RSA密钥对的构造器 
                RsaKeyPairGenerator r = new RsaKeyPairGenerator();
                //RSA密钥构造器的参数 
                RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
                    Org.BouncyCastle.Math.BigInteger.ValueOf(3),
                    new SecureRandom(),
                    1024,   //密钥长度 
                    25);
                r.Init(param);
                AsymmetricCipherKeyPair keyPair = r.GenerateKeyPair();
                //获取公钥和密钥 
                AsymmetricKeyParameter private_key = keyPair.Private;
                AsymmetricKeyParameter public_key = keyPair.Public;
                if (((RsaKeyParameters)public_key).Modulus.BitLength < 1024)
                {
                    Console.WriteLine("failed key generation (1024) length test");
                }
                using (TextWriter textWriter = new StringWriter())
                {
                    PemWriter pemWriter = new PemWriter(textWriter);
                    pemWriter.WriteObject(keyPair.Private);
                    pemWriter.Writer.Flush();
                    privateKey = textWriter.ToString();
                }
                using (TextWriter textpubWriter = new StringWriter())
                {
                    PemWriter pempubWriter = new PemWriter(textpubWriter);
                    pempubWriter.WriteObject(keyPair.Public);
                    pempubWriter.Writer.Flush();
                    publicKey = textpubWriter.ToString();                   
                }
                //keyPair = ReadPem(privateKey); // 直接读取字符串生成密码钥                 
                //public_key = keyPair.Public;//公钥  
                //private_key = keyPair.Private;//私钥 
                // 前面私钥为pkcs1格式,经过下面处理后,变成pkcs8格式
                SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(public_key);
                PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);
                Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
                byte[] publicInfoByte = asn1ObjectPublic.GetEncoded();
                Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
                byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded();

                var pubkeyb64 = Convert.ToBase64String(publicInfoByte);
                // 这里生成的是Pkcs8的密钥
                privateKeyPk8 = PrivateKeyPk8Format(Convert.ToBase64String(privateInfoByte));

                privateKey = PrivateKeyFormat(privateKey);
                publicKey = PublicKeyFormat(publicKey);
            }
            catch (Exception ex) {
                throw ex;
            }            
        }

        /// 
        /// 加载Pkcs8格式的私钥
        /// 
        /// 
        /// 
        public static AsymmetricKeyParameter loadPrivateKeyPk8(string privateKey)
        {
            try
            {
                privateKey = KeyClear(privateKey);
                byte[] prikey = Convert.FromBase64String(privateKey);
                Asn1Object priKeyObj = Asn1Object.FromByteArray(prikey);//这里也可以从流中读取,从本地导入
                AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(priKeyObj));
                return priKey;
            }
            catch (Exception)
            {
                throw new Exception("密钥格式不正确");
            }
        }

        /// 
        /// 加载Pkcs1格式的私钥
        /// 
        /// 
        /// 
        public static AsymmetricKeyParameter loadPrivateKeyPk1(string privateKey)
        {
            AsymmetricCipherKeyPair keyPair = null;
            try
            {
                keyPair = ReadPem(privateKey); // 直接读取字符串生成密码钥
            }
            catch (Exception)
            {
                throw new Exception("密钥格式不正确");
            }
            try
            {
                AsymmetricKeyParameter private_key = keyPair.Private;             
                // 前面私钥为pkcs1格式,经过下面处理后,变成pkcs8格式              
                PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);              
                Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();              
                AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(asn1ObjectPrivate));
                return priKey;
            }
            catch (Exception)
            {
                throw new Exception("加载失败");
            }          
        }

        /// 
        /// 加载公钥
        /// 
        /// 
        /// 
        public static AsymmetricKeyParameter loadPublicKey(string publicKey)
        {
            try
            {
                publicKey = KeyClear(publicKey);
                byte[] pubkey = Convert.FromBase64String(publicKey);
                Asn1Object pubKeyObj = Asn1Object.FromByteArray(pubkey);//这里也可以从流中读取,从本地导入   
                AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(SubjectPublicKeyInfo.GetInstance(pubKeyObj));
                return pubKey;
            }
            catch (Exception)
            {
                throw new Exception("密钥格式不正确");
            }
        }

        /// 
        /// 将Pkcs1格式的私转成Pkcs8格式
        /// 
        /// 
        /// 
        public static string ConvertPriPk1ToPk8(string privateKey)
        {
            AsymmetricCipherKeyPair keyPair = null;
            try
            {
                keyPair = ReadPem(privateKey); // 直接读取字符串生成密码钥
            }
            catch (Exception)
            {
                throw new Exception("密钥格式不正确");
            }
            try
            {
                AsymmetricKeyParameter private_key = keyPair.Private;
                AsymmetricKeyParameter public_key = keyPair.Public;
                // 前面私钥为pkcs1格式,经过下面处理后,变成pkcs8格式
                SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(public_key);
                PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);
                Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
                byte[] publicInfoByte = asn1ObjectPublic.GetEncoded();
                Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
                byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded();
                var pubkeyb64 = Convert.ToBase64String(publicInfoByte);
                // 这里生成的是Pkcs8的密钥
                return PrivateKeyFormat(Convert.ToBase64String(privateInfoByte));

            }
            catch (Exception)
            {
                throw new Exception("转换失败");
            }
        }

        public static string KeyClear(string key)
        {
            key = Regex.Replace(key, @"(-----BEGIN PRIVATE KEY-----)|(-----END PRIVATE KEY-----)|(-----BEGIN RSA PRIVATE KEY-----)|(-----END RSA PRIVATE KEY-----)|(-----BEGIN PUBLIC KEY-----)|(-----END PUBLIC KEY-----)|(-----BEGIN RSA PUBLIC KEY-----)|(-----END RSA PUBLIC KEY-----)|\n|\r", "");
            return key;
        }

        private static string PrivateKeyFormat(string privateKey)
        {
            privateKey = KeyClear(privateKey);
            privateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" + privateKey + "\r\n-----END RSA PRIVATE KEY-----";
            return privateKey;
        }

        private static string PrivateKeyPk8Format(string privateKey)
        {
            privateKey = KeyClear(privateKey);
            privateKey = "-----BEGIN PRIVATE KEY-----\r\n" + privateKey + "\r\n-----END PRIVATE KEY-----";
            return privateKey;
        }

        private static string PublicKeyFormat(string publicKey)
        {
            publicKey = KeyClear(publicKey);
            publicKey = "-----BEGIN PUBLIC KEY-----\r\n" + publicKey + "\r\n-----END PUBLIC KEY-----";
            return publicKey;
        }
        static AsymmetricCipherKeyPair ReadPem(string pem)
        {
            using (TextReader reader = new StringReader(pem))
            {
                var obj = new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject();
                return obj as AsymmetricCipherKeyPair;
            }
        }
    }
}

Rsa加密、解密、签名、验签工具类

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace lhtzbj12.Encryption
{
    /// 
    /// Rsa非对称加密工具类
    /// 
    public  class RsaBCHelper
    {      
        ///     
        /// 签名    
        ///     
        /// 待签名字符串    
        /// 私钥   
       
        /// 签名后字符串    
        public static string Sign(string content, string privateKey)
        {
            AsymmetricKeyParameter priKey = RsaKeyHelper.loadPrivateKeyPk1(privateKey);
            ISigner sig = SignerUtilities.GetSigner("SHA256withRSA"); //其他算法 如SHA1withRSA
            sig.Init(true, priKey);
            var bytes = Encoding.UTF8.GetBytes(content);
            sig.BlockUpdate(bytes, 0, bytes.Length);
            byte[] signature = sig.GenerateSignature();
            var signedString = Convert.ToBase64String(signature);
            return signedString;
        }

        ///     
        /// 验签    
        ///     
        /// 待验签字符串    
        /// 签名    
        /// 公钥 
        /// true(通过),false(不通过)    
        public static bool Verify(string content, string signedString, string publicKey)
        {
            AsymmetricKeyParameter pubKey = RsaKeyHelper.loadPublicKey(publicKey);
            ISigner signer = SignerUtilities.GetSigner("SHA256withRSA"); //其他算法 如SHA1withRSA
            signer.Init(false, pubKey);
            var expectedSig = Convert.FromBase64String(signedString);
            var msgBytes = Encoding.UTF8.GetBytes(content);
            signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
            return signer.VerifySignature(expectedSig);
        }       

        ///     
        /// 公钥加密    
        ///     
        /// 需要加密的字符串    
        /// 公钥  
        /// 明文    
        public static string Encrypt(string resData, string publicKey)
        {
            try
            {
                AsymmetricKeyParameter pubKey = RsaKeyHelper.loadPublicKey(publicKey);
                IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
                cipher.Init(true, pubKey);//true表示加密  
                var data = Encoding.UTF8.GetBytes(resData.Trim());
                byte[] encryptData = cipher.DoFinal(data);
                return Convert.ToBase64String(encryptData);
            }
            catch (Exception)
            {
                throw new Exception("加密失败");
            }
        }

        ///     
        /// 私钥解密
        ///     
        /// 加密字符串    
        /// 私钥    
        /// 编码格式    
        /// 明文    
        public static string Decrypt(string resData, string privateKey)
        {
            try
            {
                AsymmetricKeyParameter priKey = RsaKeyHelper.loadPrivateKeyPk1(privateKey);
                IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
                cipher.Init(false, priKey);//false表示解密  
                var encryptData = Convert.FromBase64String(resData);
                var decryptData = cipher.DoFinal(encryptData);
                return Encoding.UTF8.GetString(decryptData);
            }
            catch (Exception) {
                throw new Exception("解密失败");
            }
            
        }
        ///     
        /// 私钥加密    
        ///     
        /// 需要加密的字符串    
        /// 私钥  
        /// 明文    
        public static string EncryptByPrivateKey(string resData, string privateKey)
        {
            try
            {
                AsymmetricKeyParameter priKey = RsaKeyHelper.loadPrivateKeyPk1(privateKey);
                IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
                cipher.Init(true, priKey);//true表示加密  
                var data = Encoding.UTF8.GetBytes(resData.Trim());
                byte[] encryptData = cipher.DoFinal(data);
                return Convert.ToBase64String(encryptData);
            }
            catch (Exception)
            {
                throw new Exception("加密失败");
            }
        }

        ///     
        /// 公钥解密
        ///     
        /// 加密字符串    
        /// 公钥           
        /// 明文    
        public static string DecryptByPublicKey(string resData, string publicKey)
        {
            try
            {
                AsymmetricKeyParameter pubKey = RsaKeyHelper.loadPublicKey(publicKey);
                IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
                cipher.Init(false, pubKey);//false表示解密  
                var encryptData = Convert.FromBase64String(resData);
                var decryptData = cipher.DoFinal(encryptData);
                return Encoding.UTF8.GetString(decryptData);
            }
            catch (Exception)
            {
                throw new Exception("解密失败");
            }

        }       
    }
}

github工程源码

https://github.com/lhtzbj12/csharp_encryption

你可能感兴趣的:(C#,Des,Rsa,多语言,互通,C#,系统安全)