문제

내가 하려는 현재 구현하는 클래스를 핸들 간의 보안 통신 인스턴스의 내 응용 프로그램을 사용하여 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();
        }

    }
}

두 번째 질문:어떻게 보낼 데이터를 주고받을 수 있는 수준으로 등?나는 녹색 horn,이 분야에서 포인터 감사하겠습니다.

도움이 되었습니까?

해결책

Encrypt/Sign/Decrypt/Verify 메소드가 데이터에 대한 변수가 아닌 데이터의 매개 변수를 가져옵니다. 키와 공급자에 대한 멤버 변수를 갖는 것은 괜찮은 것 같습니다. 기본적으로 동일한 키를 여러 번 사용하지만 동일한 데이터는 아닙니다.

또한 불변으로 만들 수 있습니다. 모든 변수를 준비 적으로 만들어서 별도의 초기화 방법을 갖지 않고 생성자의 제공자에게 필요한 모든 매개 변수를 가져옵니다.

그 외에도, 당신의 요구에 대해 더 간단한 API로 기능을 감싸는 것은 괜찮습니다.

다른 팁

나는 몇몇 조정,여기에 무엇 구현은 다음과 같:

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
    }
}

너희들은 여전히지 않은 아무 말도는 방법에 대해 통신 설립(나는 생각 sockets).계몽하십시오 나.

이 코드의 코드가 당신에게 도움이 될 수 있는지 모르겠습니다.이 코드를 썼습니다.이 코드를 썼습니다. 다양한 크리 파트 algortims에서 개인/공개 키 쌍으로 크리프트하고 해독 할 수 있고 길이 문제를 암호화하기위한 데이터가없고 RSA 구현을 수행 할 수 있습니다. 순 어려움은 250 개 이상의 데이터를 관리하려고 노력합니다 (다소 미안합니다) 바이트의 데이터.

방금 필요한 방법 만 자르고 붙여 넣었습니다. XML 문서화 원인도 영어가 아니 었습니다.이 유용한 것을 발견하면 모든 소스를 게시 할 수 있습니다. 이 컷 및 페이스트 버전을 테스트하지 않았지만이 클래스의 정식 버전을 사용하지는 않았습니다.

BTW : 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

@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

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;
    }
}
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top