RSA加密/解密的问题在.NET中 [英] RSA Encrypt / Decrypt Problem in .NET

查看:160
本文介绍了RSA加密/解密的问题在.NET中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在用C#加密问题,使用RSA解密。我已经开发了将被发送敏感的财务信息和交易的Web服务。我希望能够做的就是在客户端,使用加密客户端RSA私钥,一旦达到我的服务将与客户的公钥解密某些字段。

I'm having a problem with C# encrypting and decrypting using RSA. I have developed a web service that will be sent sensitive financial information and transactions. What I would like to be able to do is on the client side, Encrypt the certain fields using the clients RSA Private key, once it has reached my service it will decrypt with the clients public key.

目前,我一直这个模数为128个字节的最大的数据进行解密超出。得到一个例外。我没有处理多用C#RSA加密,因此任何帮助将大大AP preciated。

At the moment I keep getting a "The data to be decrypted exceeds the maximum for this modulus of 128 bytes." exception. I have not dealt much with C# RSA cryptography so any help would be greatly appreciated.

这是我用来生成密钥的方法

This is the method i am using to generate the keys

private void buttonGenerate_Click(object sender, EventArgs e)
{
    string secretKey = RandomString(12, true);

    CspParameters param = new CspParameters();
    param.Flags = CspProviderFlags.UseMachineKeyStore;

    SecureString secureString = new SecureString();
    byte[] stringBytes = Encoding.ASCII.GetBytes(secretKey);
    for (int i = 0; i < stringBytes.Length; i++)
    {
        secureString.AppendChar((char)stringBytes[i]);
    }
    secureString.MakeReadOnly();
    param.KeyPassword = secureString;

    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(param);
    rsaProvider = (RSACryptoServiceProvider)RSACryptoServiceProvider.Create();
    rsaProvider.KeySize = 1024;


    string publicKey = rsaProvider.ToXmlString(false);
    string privateKey = rsaProvider.ToXmlString(true);

    Repository.RSA_XML_PRIVATE_KEY = privateKey;
    Repository.RSA_XML_PUBLIC_KEY = publicKey;

    textBoxRsaPrivate.Text = Repository.RSA_XML_PRIVATE_KEY;
    textBoxRsaPublic.Text = Repository.RSA_XML_PUBLIC_KEY;

    MessageBox.Show("Please note, when generating keys you must sign on to the gateway\n" +
        " to exhange keys otherwise transactions will fail", "Key Exchange", MessageBoxButtons.OK, MessageBoxIcon.Information);

}

在我已经生成的密钥,我送公钥来存储它作为一个XML文件中的Web服务。

Once i have generated the keys, i send the public key to the web service which stores it as an XML file.

现在我决定测试此所以这里是我的方法来加密字符串

Now i decided to test this so here is my method to encrypt a string

public static string RsaEncrypt(string dataToEncrypt)
{
    string rsaPrivate = RSA_XML_PRIVATE_KEY;
    CspParameters csp = new CspParameters();
    csp.Flags = CspProviderFlags.UseMachineKeyStore;

    RSACryptoServiceProvider provider = new RSACryptoServiceProvider(csp);

    provider.FromXmlString(rsaPrivate);

    ASCIIEncoding enc = new ASCIIEncoding();
    int numOfChars = enc.GetByteCount(dataToEncrypt);
    byte[] tempArray = enc.GetBytes(dataToEncrypt);
    byte[] result = provider.Encrypt(tempArray, true);
    string resultString = Convert.ToBase64String(result);
    Console.WriteLine("Encrypted : " + resultString);
    return resultString;
}

我得到什么似乎是一个加密值。在我创建的测试加密Web方法,然后我采取这种加密数据,尽量使用客户的公钥对数据进行解密,并将其发送回的清晰。但是,这是抛出异常。这里是我的方法负责这一点。

I do get what seems to be an encrypted value. In the test crypto web method that i created, i then take this encrypted data, try and decrypt the data using the clients public key and send this back in the clear. But this is where the exception is thrown. Here is my method responsible for this.

public string DecryptRSA(string data, string merchantId)
{
    string clearData = null;
    try
    {
        CspParameters param = new CspParameters();
        param.Flags = CspProviderFlags.UseMachineKeyStore;
        RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(param);

        string merchantRsaPublic = GetXmlRsaKey(merchantId);
        rsaProvider.FromXmlString(merchantRsaPublic);
        byte[] asciiString = Encoding.ASCII.GetBytes(data);

        byte[] decryptedData = rsaProvider.Decrypt(asciiString, false);

        clearData = Convert.ToString(decryptedData);
    }
    catch (CryptographicException ex)
    {
        Log.Error("A cryptographic error occured trying to decrypt a value for " + merchantId, ex);

    }
    return clearData;
}

如果有人可以帮助我,将是真棒,就像我说我没有做太多的C#RSA加密/解密。

If anyone could help me that would be awesome, as i have said i have not done much with C# RSA encryption/decryption.

推荐答案

让我有点术语。还有的非对称加密的并没有的数字签名

Allow me a bit of terminology. There is asymmetric encryption and there is digital signature.


  • 非对称加密大约为保持机密性。一些敏感的数据转换成不可读的东西,保存谁知道解密密钥的实体。解密密钥是一定是的私人的关键:如果解密密钥是公钥,然后每个人都可以解密数据(公共密钥,没错,是公共的)并没有保密了。在非对称加密,一用公钥加密,并与相应的私钥解密。

  • Asymmetric encryption is about keeping confidentiality. Some sensitive data is transformed into something unreadable, save for the entity who knows the decryption key. The decryption key is necessarily the private key: if the decryption key is the public key, then everybody can decrypt the data (the public key is, well, public) and there is no confidentiality anymore. In asymmetric encryption, one encrypts with the public key and decrypts with the corresponding private key.

数字签名是为了证明完整性。有人计算过的数据的种类键控校验的,以这样的方式,该校验和数据之间的链接可以在以后验证。这是一个签名,只是因为来计算校验和电源要求的东西是不为公众所知 - 以纯文字,签字使用的私人的关键。验证,但是,应该是任何人可行的,并且因此使用公钥

Digital signatures are meant to prove integrity. Someone computes a kind of keyed checksum over the data, in such a way that the link between the checksum and the data can be verified later. This is a "signature" only because the power to compute that checksum requires knowledge of something which is not public -- in plain words, signing uses the private key. Verification, however, should be doable by anybody, and thus use the public key.

混乱的公平位由以下事实的RSA算法实际上是可被拒绝到两个非对称加密系统,和一个数字签名系统中的数学运算暗示。这种混乱是由RSA标准,又名 PKCS#1 ,含蓄地依赖于如何进一步增强RSA数字签名进行了首次描述,即作为逆转加密(签名者使用自己的私钥加密数据)。这导致之类的东西RSA签名叫sha1WithRSAEncryption。这是很不幸的。

A fair bit of confusion is implied by the fact that "the" RSA algorithm is actually a mathematical operation which can be declined into both an asymmetric encryption system, and a digital signature system. The confusion is further enhanced by the RSA standard, aka PKCS#1, which implicitly relies on how RSA digital signatures were first described, i.e. as a "reversed encryption" ("the signer encrypts the data with his private key"). Which leads to things like RSA signatures called "sha1WithRSAEncryption". This is quite unfortunate.

因此​​,你必须首先决定是否要保密或签名。为了保密,数据发送的的客户的服务器,该服务器将拥有私人密钥,客户端使用的的服务器公钥加密的数据。对于签名,每个客户端应有自己的私人密钥,并用它来对数据签名,和服务器验证签名。从你的描述我不能告诉你是真正之后,由于我提及上面的混乱。

Therefore, you must first decide whether you want confidentiality or signatures. For confidentiality, for data sent from clients to the server, the server shall own a private key, and the clients use the server public key to encrypt the data. For signatures, each client shall have his own private key and use it to sign the data, and the server verifies the signatures. From your description I cannot tell what you are really after, thanks to the confusion I allude to above.

此外,还有一些所谓的验证的可能看起来像数字签名,但较弱。签名的点比的任何的可以验证签名。特别是,签名可以证明法官,因此可作为法律武器的的签名(签名是具有法律约束力的 - 至少,如果你这样做的权利,并在规定的当前状态在电子签名,这是不容易的)。在大多数情况下,你只需要一些更弱和更简单,其中的服务器是确信,它谈论的权利客户端,但无法说服事后别人,这个客户是真的存在。任何网站与用户密码使用这样的认证。

Also, there is something called authentication which may look like digital signatures, but is weaker. The point of signatures is than anybody can verify the signature. In particular, the signature can be shown to a judge and thus serve as legal weapon against the signer (the signature is legally binding -- at least if you do it right, and in the current state of regulations over electronic signatures, this is not easy). In most situations you only need something weaker and simpler, in which the server is convinced that it talks to the right client, but cannot afterwards convince anybody else that this client was really there. Any web site with user passwords is using such authentication.

有了这样说......

With that being said...


  • RSA非对称加密只涉及短消息。对于一个1024位RSA密钥(即一键,其中最重要的部分,在RSA模,是加密消息2 ^ 1023和2 ^ 1024之间的值,和一个大数目将长度为128字节)加密邮件的最大大小为117字节(这是你的错误消息的实际来源)。当我们要发送较长的消息,我们使用一个混合系统,在此我们只加密一小束随机比特(说128比特),并使用该束作为用于对称加密的系统的关键(例如:AES),它可以处理更长消息(和更快,太)。

  • RSA asymmetric encryption covers only short messages. For a 1024-bit RSA key (i.e. a key where the most important part, the "RSA modulus", is a big number with a value between 2^1023 and 2^1024, and encrypted messages will be of length 128 bytes), the maximum size of an encrypted message is 117 bytes (that's the actual source of your error message). When we want to send longer messages, we use an hybrid system, in which we only encrypt a small bunch of random bits (say 128 bits) and use that bunch as a key for a symmetric encryption system (e.g. AES) which can process much longer messages (and much faster, too).

RSA签名,同样的,只能在短消息来计算的,因此,一个签名实际上是在计算散列值的PKCS#1标准要求。散列值是一个具体的散列函数的,其上计算对消息进行签名的输出。散列函数具有固定尺寸的输出(用于SHA-256例如256比特),但接受(几乎)任意长度的输入消息。哈希函数是公共的(没有在他们没有钥匙),并进行适当的安全性,必须有一些特殊的性质。 SHA-256,现在,不是一个坏的选择。 SHA-1(SHA-256的一个predecessor)已被证明有一定的缺点,应避免使用。 MD5有(一种-的SHA-1的叔叔)有较大的弱点,不得使用。

RSA signatures, similarly, can be computed only on short messages, hence the PKCS#1 standard mandates that a signature is actually computed over a hash value. The hash value is the output of a specific hash function, which is computed over the message to sign. The hash function has a fixed-sized output (e.g. 256 bits for SHA-256) but accepts input messages of (almost) arbitrary length. Hash functions are public (there is no key in them) and, for proper security, must have some special properties. SHA-256 is, right now, not a bad choice. SHA-1 (a predecessor of SHA-256) has been proven to have some weaknesses and should be avoided. MD5 has (a kind-of uncle of SHA-1) has bigger weaknesses and shall not be used.

正确使用的非对称加密,尤其是在混合动力方案,数字签名,是比上面的文字可能会建议棘手。这是非常容易理解错误在某些时候,的无形的,即code会出现工作,但会泄露攻击者有用的数据。在右侧办法使用非对称加密和数字签名是依靠现有的,胸有成竹的协议。协议是加密的元素成一个连贯的系统,在这里泄漏照顾的集合。最典型的例子是TLS,也称为SSL。它是保证机密数据传输,完整性和认证(可能相互认证)的协议。 HTTPS协议是HTTP和SSL的混合物。光明的一面是,HTTPS拥有现有的实现,特别是在C#。在code是最容易实现和调试是code已经被执行和调试。因此,使用HTTPS,你会活得更长,更快乐。

Proper use of asymmetric encryption, especially in an hybrid scheme, and digital signatures, is trickier than what the text above may suggest. It is awfully easy to get it wrong at some point, invisibly, i.e. the code will appear to work but will leak data useful for an attacker. The right way to use asymmetric encryption or digital signatures is to rely on existing, well-thought protocols. A protocol is an assembly of cryptographic elements into a coherent system, where leaks are taken care of. The prime example is TLS, also known as SSL. It is a protocol which ensures confidential data transmission, with integrity and authentication (possibly mutual authentication). The HTTPS protocol is a mixture of HTTP and SSL. The bright side is that HTTPS has existing implementations, notably in C#. The code which is easiest to implement and debug is the code which has already been implemented and debugged. So use HTTPS and you will live longer and happier.

这篇关于RSA加密/解密的问题在.NET中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆