在 C# 中实现 RSA

发布于 2024-07-11 10:52:25 字数 1663 浏览 6 评论 0原文

我目前正在尝试实现一个类来使用 RSACrytoServiceProveider 类处理我的应用程序实例之间的安全通信。 第一个问题:实现一个类来处理发送者/接收者角色是个好主意还是应该将角色分成单独的类? 这就是我到目前为止所做的:

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

namespace Agnus.Cipher
{
    public class RSA
    {
        private byte[] plaintextBytes;
        private byte[] ciphertextBytes;
        private RSACryptoServiceProvider rSAProviderThis;
        private RSACryptoServiceProvider rSAProviderOther;

        public string PublicKey
        {
            get { return rSAProviderThis.ToXmlString(false); }
        }

        public RSA()
        {
            rSAProviderThis = new RSACryptoServiceProvider { PersistKeyInCsp = true }; 
            plaintextBytes = Encoding.Unicode.GetBytes(PublicKey);
        }

        public void InitializeRSAProviderOther(string parameters)
        {
            rSAProviderOther.FromXmlString(parameters);
        }

        public byte[] Encrypt()
        {
            return rSAProviderThis.Encrypt(plaintextBytes, true);
        }
        public byte[] Decrypt()
        {
            return rSAProviderThis.Decrypt(ciphertextBytes, true);
        }
        public byte[] Sign()
        {
            using (SHA1Managed SHA1 = new SHA1Managed())
            {
                byte[] hash = SHA1.ComputeHash(ciphertextBytes);
                byte[] signature = rSAProviderThis.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
                return signature;
            }
        }
        public void Verify()
        {
            throw new NotImplementedException();
        }

    }
}

第二个问题:我如何发送和接收要输入到班级中的数据? 我是这个领域的新手,将不胜感激。

I'm currently trying to implement a class to handle secure communications between instances of my app using RSACrytoServiceProveider class.
First question : is it a good idea implement a single class to handle sender/reciever roles or should i split the roles into individual classes ?. This is what i have done so far:

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

namespace Agnus.Cipher
{
    public class RSA
    {
        private byte[] plaintextBytes;
        private byte[] ciphertextBytes;
        private RSACryptoServiceProvider rSAProviderThis;
        private RSACryptoServiceProvider rSAProviderOther;

        public string PublicKey
        {
            get { return rSAProviderThis.ToXmlString(false); }
        }

        public RSA()
        {
            rSAProviderThis = new RSACryptoServiceProvider { PersistKeyInCsp = true }; 
            plaintextBytes = Encoding.Unicode.GetBytes(PublicKey);
        }

        public void InitializeRSAProviderOther(string parameters)
        {
            rSAProviderOther.FromXmlString(parameters);
        }

        public byte[] Encrypt()
        {
            return rSAProviderThis.Encrypt(plaintextBytes, true);
        }
        public byte[] Decrypt()
        {
            return rSAProviderThis.Decrypt(ciphertextBytes, true);
        }
        public byte[] Sign()
        {
            using (SHA1Managed SHA1 = new SHA1Managed())
            {
                byte[] hash = SHA1.ComputeHash(ciphertextBytes);
                byte[] signature = rSAProviderThis.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
                return signature;
            }
        }
        public void Verify()
        {
            throw new NotImplementedException();
        }

    }
}

Second question : how do i send and receive data to be fed into the class ? i'm a green horn in this field, pointers would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

吃素的狼 2024-07-18 10:52:25

我会让加密/签名/解密/验证方法采用数据参数,而不是为其提供成员变量。 不过,拥有密钥和提供者的成员变量似乎没问题。 基本上我希望多次使用相同的密钥但不使用相同的数据。

我还将其设置为不可变 - 将所有变量设置为只读,在构造函数中获取提供程序所需的所有参数,而不是使用单独的初始化方法。

除此之外,将功能包装在一个更简单的 API 中以满足您的需求似乎是可以的,是的。

I would make the encrypt/sign/decrypt/verify methods take parameters for the data rather than having member variables for them. Having member variables for the key and provider seems okay though. Basically I'd expect to use the same key multiple times but not the same data.

I'd also make it immutable - make all the variables readonly, taking all the parameters you'll need for the providers in the constructor instead of having a separate initialisation method.

Beyond that, it seems okay to wrap the functionality in a simpler API for your needs though, yes.

情释 2024-07-18 10:52:25

我做了一些调整,这是实现的样子:

using System;
using System.Security.Cryptography;

namespace Agnus.Cipher
{
    public class RSA : IDisposable
    {
        private RSACryptoServiceProvider rSAProviderThis;
        private RSACryptoServiceProvider rSAProviderOther = null;

        public string PublicKey
        {
            get { return rSAProviderThis.ToXmlString(false); }
        }

        public RSA()
        {
            rSAProviderThis = new RSACryptoServiceProvider { PersistKeyInCsp = true }; 
        }

        public void InitializeRSAProviderOther(string parameters)
        {
            rSAProviderOther.FromXmlString(parameters);
        }

        public byte[] Encrypt(byte[] plaintextBytes)
        {
                return rSAProviderThis.Encrypt(plaintextBytes, true);
        }
        public string  Decrypt(byte[] ciphertextBytes)
        {
            try
            {
                return Convert.ToBase64String( rSAProviderThis.Decrypt(ciphertextBytes, true));
            }
            catch (CryptographicException ex)
            {
                Console.WriteLine("Unable to decrypt: " + ex.Message + " " + ex.StackTrace);
            }
            finally
            {
                this.Dispose();
            }
            return string.Empty;
        }
        public string SignData(byte[] ciphertextBytes)
        {
            string  signature = GenerateSignature(ciphertextBytes, rSAProviderThis);
            return signature;
        }

        private string GenerateSignature(byte[] ciphertextBytes, RSACryptoServiceProvider provider)
        {
            using (SHA1Managed SHA1 = new SHA1Managed())
            {
                byte[] hash = SHA1.ComputeHash(ciphertextBytes);
                string signature = Convert.ToBase64String(provider.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")));
                return signature;
            }

        }

        public string  VerifySignature(byte[] ciphertextBytes, string parameters, string signatureToVerify)
        {
            InitializeRSAProviderOther(parameters);
            string actualSignature = GenerateSignature(ciphertextBytes, rSAProviderOther);
            if (actualSignature.Equals(signatureToVerify))
            {
                //verification successful
                string decryptedData = this.Decrypt(ciphertextBytes);
                return decryptedData;
                //decryptedData is a symmetric key
            }
            else
            {
                //verification unsuccessful
                //end session
            }
            return string.Empty;
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (rSAProviderOther != null)
            {
                rSAProviderOther.Clear();
            }
            rSAProviderThis.Clear();
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}

你们仍然没有提到如何建立通信(我正在考虑套接字)。 请赐教。

I have made some adjustments, here is what the implementation looks like:

using System;
using System.Security.Cryptography;

namespace Agnus.Cipher
{
    public class RSA : IDisposable
    {
        private RSACryptoServiceProvider rSAProviderThis;
        private RSACryptoServiceProvider rSAProviderOther = null;

        public string PublicKey
        {
            get { return rSAProviderThis.ToXmlString(false); }
        }

        public RSA()
        {
            rSAProviderThis = new RSACryptoServiceProvider { PersistKeyInCsp = true }; 
        }

        public void InitializeRSAProviderOther(string parameters)
        {
            rSAProviderOther.FromXmlString(parameters);
        }

        public byte[] Encrypt(byte[] plaintextBytes)
        {
                return rSAProviderThis.Encrypt(plaintextBytes, true);
        }
        public string  Decrypt(byte[] ciphertextBytes)
        {
            try
            {
                return Convert.ToBase64String( rSAProviderThis.Decrypt(ciphertextBytes, true));
            }
            catch (CryptographicException ex)
            {
                Console.WriteLine("Unable to decrypt: " + ex.Message + " " + ex.StackTrace);
            }
            finally
            {
                this.Dispose();
            }
            return string.Empty;
        }
        public string SignData(byte[] ciphertextBytes)
        {
            string  signature = GenerateSignature(ciphertextBytes, rSAProviderThis);
            return signature;
        }

        private string GenerateSignature(byte[] ciphertextBytes, RSACryptoServiceProvider provider)
        {
            using (SHA1Managed SHA1 = new SHA1Managed())
            {
                byte[] hash = SHA1.ComputeHash(ciphertextBytes);
                string signature = Convert.ToBase64String(provider.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")));
                return signature;
            }

        }

        public string  VerifySignature(byte[] ciphertextBytes, string parameters, string signatureToVerify)
        {
            InitializeRSAProviderOther(parameters);
            string actualSignature = GenerateSignature(ciphertextBytes, rSAProviderOther);
            if (actualSignature.Equals(signatureToVerify))
            {
                //verification successful
                string decryptedData = this.Decrypt(ciphertextBytes);
                return decryptedData;
                //decryptedData is a symmetric key
            }
            else
            {
                //verification unsuccessful
                //end session
            }
            return string.Empty;
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (rSAProviderOther != null)
            {
                rSAProviderOther.Clear();
            }
            rSAProviderThis.Clear();
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}

you guys still haven't said anything about how communication is going to be established (i'm thinking sockets). Please enlighten me.

孤独陪着我 2024-07-18 10:52:25

我不知道这段代码是否对您有帮助,我编写这段代码是为了能够在不同的加密算法中使用私钥/公钥对进行加密和解密,并且没有数据加密长度问题,事实上 .当您尝试管理超过 250 个字节(或多或少,抱歉我不记得了)的数据时,. NET 会受到影响。

我只是剪切和粘贴所需的方法,我还剪切了 xml 文档,因为不是英文,如果您发现这有用,请告诉我,我可以发布所有源代码。 我再说一遍,我没有测试这个剪切和粘贴版本,但我使用了这个类的完整版本,它没有那么不同。

顺便说一句:它是用 VB 编写的,但如果你只是需要潜伏它,我认为这就足够了;)

Namespace Crypto

    Public Class RSACry

        Shared Sub New()
        End Sub

        Public Enum Algorithms
            DES
            TDES
            RC2
            RDAEL
        End Enum

        Public Shared Function Encrypt(ByVal xmlkeystring As String, ByVal typo As Algorithms, ByVal datatoencrypt As String) As String
            Dim rsaer As RSA = Crypto.RSACry.ReadKeyString(xmlkeystring)
            Dim result() As Byte = Crypto.RSACry.EncryptIt(rsaer, typo, datatoencrypt)
            Return System.Convert.ToBase64String(result)
        End Function

        Public Shared Function Decrypt(ByVal xmlkeystring As String, ByVal typo As Algorithms, ByVal datatodecrypt As String) As String
            Dim rsaer As RSA = Crypto.RSACry.ReadKeyString(xmlkeystring)
            Dim result() As Byte = Crypto.RSACry.DecryptIt(rsaer, typo, datatodecrypt)
            Return System.Text.Encoding.UTF8.GetString(result)
        End Function

        Friend Shared Function EncryptIt(ByRef rsaer As RSA, ByVal typo As Algorithms, ByVal datatoencrypt As String) As Byte()
            Dim result() As Byte = Nothing

            Try
                Dim plainbytes() As Byte = System.Text.Encoding.UTF8.GetBytes(datatoencrypt)
                Dim sa As SymmetricAlgorithm = SymmetricAlgorithm.Create(Crypto.RSACry.GetAlgorithmName(typo))
                Dim ct As ICryptoTransform = sa.CreateEncryptor()
                Dim encrypt() As Byte = ct.TransformFinalBlock(plainbytes, 0, plainbytes.Length)
                Dim fmt As RSAPKCS1KeyExchangeFormatter = New RSAPKCS1KeyExchangeFormatter(rsaer)
                Dim keyex() As Byte = fmt.CreateKeyExchange(sa.Key)

                --return the key exchange, the IV (public) and encrypted data 
                result = New Byte(keyex.Length + sa.IV.Length + encrypt.Length) {}
                Buffer.BlockCopy(keyex, 0, result, 0, keyex.Length)
                Buffer.BlockCopy(sa.IV, 0, result, keyex.Length, sa.IV.Length)
                Buffer.BlockCopy(encrypt, 0, result, keyex.Length + sa.IV.Length, encrypt.Length)

            Catch ex As Exception
                Throw New CryptographicException("Unable to crypt: " + ex.Message)
            End Try

            Return result
        End Function

        Friend Shared Function DecryptIt(ByRef rsaer As RSA, ByVal typo As Algorithms, ByVal datatodecrypt As String) As Byte()
            Dim result() As Byte = Nothing

            Try
                Dim encrbytes() As Byte = System.Convert.FromBase64String(datatodecrypt)
                Dim sa As SymmetricAlgorithm = SymmetricAlgorithm.Create(Crypto.RSACry.GetAlgorithmName(typo))
                Dim keyex() As Byte = New Byte((rsaer.KeySize >> 3) - 1) {}
                Buffer.BlockCopy(encrbytes, 0, keyex, 0, keyex.Length)

                Dim def As RSAPKCS1KeyExchangeDeformatter = New RSAPKCS1KeyExchangeDeformatter(rsaer)
                Dim key() As Byte = def.DecryptKeyExchange(keyex)
                Dim iv() As Byte = New Byte((sa.IV.Length - 1)) {}
                Buffer.BlockCopy(encrbytes, keyex.Length, iv, 0, iv.Length)

                Dim ct As ICryptoTransform = sa.CreateDecryptor(key, iv)
                result = ct.TransformFinalBlock(encrbytes, keyex.Length + iv.Length, (encrbytes.Length - 1) - (keyex.Length + iv.Length))
            Catch ex As Exception
                Throw New CryptographicException("Unable to decrypt: " + ex.Message)
            End Try

            Return result
        End Function    

        Friend Shared Function GetAlgorithmName(ByVal typo As Algorithms) As String
            Dim algtype As String = String.Empty

            Select Case typo
                Case Algorithms.DES
                    Return "DES"
                    Exit Select
                Case Algorithms.RC2
                    Return "RC2"
                    Exit Select
                Case Algorithms.RDAEL
                    Return "Rijndael"
                    Exit Select
                Case Algorithms.TDES
                    Return "TripleDES"
                    Exit Select
                Case Else
                    Return "Rijndael"
                    Exit Select
            End Select

            Return algtype
        End Function

        Friend Shared Function ReadKeyString(ByVal xmlkeystring As String) As RSA
            Dim rsaer As RSA = Nothing

            Try
                If (String.IsNullOrEmpty(xmlkeystring)) Then Throw New Exception("Key is not specified")
                rsaer = RSA.Create()
                rsaer.FromXmlString(xmlkeystring)
            Catch ex As Exception
                Throw New CryptographicException("Unable to load key")
            End Try

            Return rsaer
        End Function    

End Namespace

I don't know if this snip of code may help you, I've wrote this code to be able to crypt and decrypt with private/public key pairs in diverse crypting algortims and without data to encrypt length issue, infact RSA implementation in .NET suffer whe you try to manage more than 250 (more or less, sorry I don't recall) bytes of data.

I just cut and paste only methods needed, I also cutted xml documentation cause is not in english, if you found this useful let me know, I can post all source. I repeat I do not tested this cut&paste version, but I used the full version of this class that is not that different.

BTW: it's in VB, but if you just need to lurk at it I think it's enough ;)

Namespace Crypto

    Public Class RSACry

        Shared Sub New()
        End Sub

        Public Enum Algorithms
            DES
            TDES
            RC2
            RDAEL
        End Enum

        Public Shared Function Encrypt(ByVal xmlkeystring As String, ByVal typo As Algorithms, ByVal datatoencrypt As String) As String
            Dim rsaer As RSA = Crypto.RSACry.ReadKeyString(xmlkeystring)
            Dim result() As Byte = Crypto.RSACry.EncryptIt(rsaer, typo, datatoencrypt)
            Return System.Convert.ToBase64String(result)
        End Function

        Public Shared Function Decrypt(ByVal xmlkeystring As String, ByVal typo As Algorithms, ByVal datatodecrypt As String) As String
            Dim rsaer As RSA = Crypto.RSACry.ReadKeyString(xmlkeystring)
            Dim result() As Byte = Crypto.RSACry.DecryptIt(rsaer, typo, datatodecrypt)
            Return System.Text.Encoding.UTF8.GetString(result)
        End Function

        Friend Shared Function EncryptIt(ByRef rsaer As RSA, ByVal typo As Algorithms, ByVal datatoencrypt As String) As Byte()
            Dim result() As Byte = Nothing

            Try
                Dim plainbytes() As Byte = System.Text.Encoding.UTF8.GetBytes(datatoencrypt)
                Dim sa As SymmetricAlgorithm = SymmetricAlgorithm.Create(Crypto.RSACry.GetAlgorithmName(typo))
                Dim ct As ICryptoTransform = sa.CreateEncryptor()
                Dim encrypt() As Byte = ct.TransformFinalBlock(plainbytes, 0, plainbytes.Length)
                Dim fmt As RSAPKCS1KeyExchangeFormatter = New RSAPKCS1KeyExchangeFormatter(rsaer)
                Dim keyex() As Byte = fmt.CreateKeyExchange(sa.Key)

                --return the key exchange, the IV (public) and encrypted data 
                result = New Byte(keyex.Length + sa.IV.Length + encrypt.Length) {}
                Buffer.BlockCopy(keyex, 0, result, 0, keyex.Length)
                Buffer.BlockCopy(sa.IV, 0, result, keyex.Length, sa.IV.Length)
                Buffer.BlockCopy(encrypt, 0, result, keyex.Length + sa.IV.Length, encrypt.Length)

            Catch ex As Exception
                Throw New CryptographicException("Unable to crypt: " + ex.Message)
            End Try

            Return result
        End Function

        Friend Shared Function DecryptIt(ByRef rsaer As RSA, ByVal typo As Algorithms, ByVal datatodecrypt As String) As Byte()
            Dim result() As Byte = Nothing

            Try
                Dim encrbytes() As Byte = System.Convert.FromBase64String(datatodecrypt)
                Dim sa As SymmetricAlgorithm = SymmetricAlgorithm.Create(Crypto.RSACry.GetAlgorithmName(typo))
                Dim keyex() As Byte = New Byte((rsaer.KeySize >> 3) - 1) {}
                Buffer.BlockCopy(encrbytes, 0, keyex, 0, keyex.Length)

                Dim def As RSAPKCS1KeyExchangeDeformatter = New RSAPKCS1KeyExchangeDeformatter(rsaer)
                Dim key() As Byte = def.DecryptKeyExchange(keyex)
                Dim iv() As Byte = New Byte((sa.IV.Length - 1)) {}
                Buffer.BlockCopy(encrbytes, keyex.Length, iv, 0, iv.Length)

                Dim ct As ICryptoTransform = sa.CreateDecryptor(key, iv)
                result = ct.TransformFinalBlock(encrbytes, keyex.Length + iv.Length, (encrbytes.Length - 1) - (keyex.Length + iv.Length))
            Catch ex As Exception
                Throw New CryptographicException("Unable to decrypt: " + ex.Message)
            End Try

            Return result
        End Function    

        Friend Shared Function GetAlgorithmName(ByVal typo As Algorithms) As String
            Dim algtype As String = String.Empty

            Select Case typo
                Case Algorithms.DES
                    Return "DES"
                    Exit Select
                Case Algorithms.RC2
                    Return "RC2"
                    Exit Select
                Case Algorithms.RDAEL
                    Return "Rijndael"
                    Exit Select
                Case Algorithms.TDES
                    Return "TripleDES"
                    Exit Select
                Case Else
                    Return "Rijndael"
                    Exit Select
            End Select

            Return algtype
        End Function

        Friend Shared Function ReadKeyString(ByVal xmlkeystring As String) As RSA
            Dim rsaer As RSA = Nothing

            Try
                If (String.IsNullOrEmpty(xmlkeystring)) Then Throw New Exception("Key is not specified")
                rsaer = RSA.Create()
                rsaer.FromXmlString(xmlkeystring)
            Catch ex As Exception
                Throw New CryptographicException("Unable to load key")
            End Try

            Return rsaer
        End Function    

End Namespace
睫毛溺水了 2024-07-18 10:52:25

@gogole:
实际上我不使用套接字,此代码以独立方式使用,并带有手工携带的密钥。
然而,一旦你有了你的加密机制,你的旅程就已经完成一半以上了。

这里缺少两个创建密钥的方法,正如您所要求的代码是完整的。
我希望你觉得这有帮助

Public Shared Sub CreateKeyPair(ByVal filename As String)
    Dim xmlpublic As String = String.Empty
    Dim xmlprivate As String = String.Empty

    CreateKeyPair(xmlpublic, xmlprivate)

    Try
        Dim writer As New StreamWriter(filename + ".prv")
        writer.Write(xmlprivate)
        writer.Flush()
        writer.Close()
    Catch ex As Exception
        Throw New CryptographicException("Unable to write private key file: " + ex.Message)
    End Try

    Try
        Dim writer = New StreamWriter(filename + ".pub")
        writer.Write(xmlpublic)
        writer.Flush()
        writer.Close()
    Catch ex As Exception
        Throw New CryptographicException("Unable to write public key file: " + ex.Message)
    End Try
End Sub

Public Shared Sub CreateKeyPair(ByRef xmlpublic As String, ByRef xmlprivate As String)
    Dim rsa As RSA = Nothing

    Try
        rsa.Create()
    Catch ex As Exception
        Throw New CryptographicException("Unable to initialize keys: " + ex.Message)
    End Try

    Try
        xmlpublic = rsa.ToXmlString(True)
    Catch ex As Exception
        Throw New CryptographicException("Unable to generate public key: " + ex.Message)
    End Try

    Try
        xmlprivate = rsa.ToXmlString(False)
    Catch ex As Exception
        Throw New CryptographicException("Unable to generate private key: " + ex.Message)
    End Try
End Sub

@gogole:
actually I don't use sockets, this code is used in stand alone way with keys hand-bringed.
However once you have your crypt mechanism, you're at more than half of the journey.

Here there are two missing methods to create keys, as you requested the code is complete.
I hope you found this helpful

Public Shared Sub CreateKeyPair(ByVal filename As String)
    Dim xmlpublic As String = String.Empty
    Dim xmlprivate As String = String.Empty

    CreateKeyPair(xmlpublic, xmlprivate)

    Try
        Dim writer As New StreamWriter(filename + ".prv")
        writer.Write(xmlprivate)
        writer.Flush()
        writer.Close()
    Catch ex As Exception
        Throw New CryptographicException("Unable to write private key file: " + ex.Message)
    End Try

    Try
        Dim writer = New StreamWriter(filename + ".pub")
        writer.Write(xmlpublic)
        writer.Flush()
        writer.Close()
    Catch ex As Exception
        Throw New CryptographicException("Unable to write public key file: " + ex.Message)
    End Try
End Sub

Public Shared Sub CreateKeyPair(ByRef xmlpublic As String, ByRef xmlprivate As String)
    Dim rsa As RSA = Nothing

    Try
        rsa.Create()
    Catch ex As Exception
        Throw New CryptographicException("Unable to initialize keys: " + ex.Message)
    End Try

    Try
        xmlpublic = rsa.ToXmlString(True)
    Catch ex As Exception
        Throw New CryptographicException("Unable to generate public key: " + ex.Message)
    End Try

    Try
        xmlprivate = rsa.ToXmlString(False)
    Catch ex As Exception
        Throw New CryptographicException("Unable to generate private key: " + ex.Message)
    End Try
End Sub
猫烠⑼条掵仅有一顆心 2024-07-18 10:52:25

对 vb 不太了解,但尝试将 @Andrea Celin 转换为 c# 中有用的代码之一

namespace Crypto
{
using System;
using System.Security.Cryptography;
class RSACry
{
    public enum Algorithms
    {
        DES,
        TDES,
        RC2,
        RDAEL
    };
    public string Encrypt(string xmlkeystring, Algorithms typo, string datatoencrypt)
    {
        RSA rsaer = RSACry.ReadKeyString(xmlkeystring);
        byte[] result = RSACry.EncryptIt(rsaer, typo, datatoencrypt);
        return System.Convert.ToBase64String(result);
    }

    public string Decrypt(string xmlkeystring,Algorithms typo,string datatodecrypt)
    {
        RSA rsaer = RSACry.ReadKeyString(xmlkeystring);
        byte[] result =RSACry.DecryptIt(rsaer, typo, datatodecrypt);
        return System.Text.Encoding.UTF8.GetString(result);
    }

    public static byte[] EncryptIt(RSA rsaer, Algorithms typo, string datatoencrypt)
    {
        byte[] result = null;
        try
        {
            byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(datatoencrypt);
            SymmetricAlgorithm sa = SymmetricAlgorithm.Create(RSACry.GetAlgorithmName(typo));
            ICryptoTransform ct = sa.CreateEncryptor();
            byte[] encrypt = ct.TransformFinalBlock(plainbytes, 0, plainbytes.Length);
            RSAPKCS1KeyExchangeFormatter fmt = new RSAPKCS1KeyExchangeFormatter(rsaer);
            byte[] keyex = fmt.CreateKeyExchange(sa.Key);

            //--return the key exchange, the IV (public) and encrypted data 
            result = new byte[keyex.Length + sa.IV.Length + encrypt.Length];
            Buffer.BlockCopy(keyex, 0, result, 0, keyex.Length);
            Buffer.BlockCopy(sa.IV, 0, result, keyex.Length, sa.IV.Length);
            Buffer.BlockCopy(encrypt, 0, result, keyex.Length + sa.IV.Length, encrypt.Length);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("Unable to crypt: " + ex.Message);
        }
        return result;
    }

    public static byte[] DecryptIt(RSA rsaer, Algorithms typo, string datatodecrypt)
    {
        byte[] result = null;

        try
        {
            byte[] encrbytes = System.Convert.FromBase64String(datatodecrypt);
            SymmetricAlgorithm sa = SymmetricAlgorithm.Create(RSACry.GetAlgorithmName(typo));
            byte[] keyex = new byte[(rsaer.KeySize >> 3) - 1];
            Buffer.BlockCopy(encrbytes, 0, keyex, 0, keyex.Length);

            RSAPKCS1KeyExchangeDeformatter def = new RSAPKCS1KeyExchangeDeformatter(rsaer);
            byte[] key = def.DecryptKeyExchange(keyex);
            byte[] iv = new byte[sa.IV.Length - 1];
            Buffer.BlockCopy(encrbytes, keyex.Length, iv, 0, iv.Length);

            ICryptoTransform ct = sa.CreateDecryptor(key, iv);
            result = ct.TransformFinalBlock(encrbytes, keyex.Length + iv.Length, (encrbytes.Length - 1) - (keyex.Length + iv.Length));
        }
        catch (Exception ex)
        {
            throw new CryptographicException("Unable to decrypt: " + ex.Message);
        }

        return result;
    }

    public static string GetAlgorithmName(Algorithms typo)
    {
        string algtype = String.Empty;
        switch(typo)
        {
            case Algorithms.DES:
                algtype = "DES";
                break;
            case Algorithms.RC2:
                algtype = "RC2";
                break;
            case Algorithms.RDAEL:
                algtype = "Rijndael";
                break;
            case Algorithms.TDES:
                algtype = "TripleDES";
                break;
            default:
                algtype = "Rijndael";
                break;
        }
        return algtype;
    }

    public static RSA ReadKeyString(string xmlkeystring)
    {
        RSA rsaer = null;
        try
        {
            if (String.IsNullOrEmpty(xmlkeystring))
            { throw new Exception("Key is not specified"); }
            rsaer = RSA.Create();
            rsaer.FromXmlString(xmlkeystring);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("Unable to load key :"+ex.Message);
        }
        return rsaer;
    }
}
}

Does not know much vb but tried to convert @Andrea Celin one of useful Code in c#

namespace Crypto
{
using System;
using System.Security.Cryptography;
class RSACry
{
    public enum Algorithms
    {
        DES,
        TDES,
        RC2,
        RDAEL
    };
    public string Encrypt(string xmlkeystring, Algorithms typo, string datatoencrypt)
    {
        RSA rsaer = RSACry.ReadKeyString(xmlkeystring);
        byte[] result = RSACry.EncryptIt(rsaer, typo, datatoencrypt);
        return System.Convert.ToBase64String(result);
    }

    public string Decrypt(string xmlkeystring,Algorithms typo,string datatodecrypt)
    {
        RSA rsaer = RSACry.ReadKeyString(xmlkeystring);
        byte[] result =RSACry.DecryptIt(rsaer, typo, datatodecrypt);
        return System.Text.Encoding.UTF8.GetString(result);
    }

    public static byte[] EncryptIt(RSA rsaer, Algorithms typo, string datatoencrypt)
    {
        byte[] result = null;
        try
        {
            byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(datatoencrypt);
            SymmetricAlgorithm sa = SymmetricAlgorithm.Create(RSACry.GetAlgorithmName(typo));
            ICryptoTransform ct = sa.CreateEncryptor();
            byte[] encrypt = ct.TransformFinalBlock(plainbytes, 0, plainbytes.Length);
            RSAPKCS1KeyExchangeFormatter fmt = new RSAPKCS1KeyExchangeFormatter(rsaer);
            byte[] keyex = fmt.CreateKeyExchange(sa.Key);

            //--return the key exchange, the IV (public) and encrypted data 
            result = new byte[keyex.Length + sa.IV.Length + encrypt.Length];
            Buffer.BlockCopy(keyex, 0, result, 0, keyex.Length);
            Buffer.BlockCopy(sa.IV, 0, result, keyex.Length, sa.IV.Length);
            Buffer.BlockCopy(encrypt, 0, result, keyex.Length + sa.IV.Length, encrypt.Length);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("Unable to crypt: " + ex.Message);
        }
        return result;
    }

    public static byte[] DecryptIt(RSA rsaer, Algorithms typo, string datatodecrypt)
    {
        byte[] result = null;

        try
        {
            byte[] encrbytes = System.Convert.FromBase64String(datatodecrypt);
            SymmetricAlgorithm sa = SymmetricAlgorithm.Create(RSACry.GetAlgorithmName(typo));
            byte[] keyex = new byte[(rsaer.KeySize >> 3) - 1];
            Buffer.BlockCopy(encrbytes, 0, keyex, 0, keyex.Length);

            RSAPKCS1KeyExchangeDeformatter def = new RSAPKCS1KeyExchangeDeformatter(rsaer);
            byte[] key = def.DecryptKeyExchange(keyex);
            byte[] iv = new byte[sa.IV.Length - 1];
            Buffer.BlockCopy(encrbytes, keyex.Length, iv, 0, iv.Length);

            ICryptoTransform ct = sa.CreateDecryptor(key, iv);
            result = ct.TransformFinalBlock(encrbytes, keyex.Length + iv.Length, (encrbytes.Length - 1) - (keyex.Length + iv.Length));
        }
        catch (Exception ex)
        {
            throw new CryptographicException("Unable to decrypt: " + ex.Message);
        }

        return result;
    }

    public static string GetAlgorithmName(Algorithms typo)
    {
        string algtype = String.Empty;
        switch(typo)
        {
            case Algorithms.DES:
                algtype = "DES";
                break;
            case Algorithms.RC2:
                algtype = "RC2";
                break;
            case Algorithms.RDAEL:
                algtype = "Rijndael";
                break;
            case Algorithms.TDES:
                algtype = "TripleDES";
                break;
            default:
                algtype = "Rijndael";
                break;
        }
        return algtype;
    }

    public static RSA ReadKeyString(string xmlkeystring)
    {
        RSA rsaer = null;
        try
        {
            if (String.IsNullOrEmpty(xmlkeystring))
            { throw new Exception("Key is not specified"); }
            rsaer = RSA.Create();
            rsaer.FromXmlString(xmlkeystring);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("Unable to load key :"+ex.Message);
        }
        return rsaer;
    }
}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文