在C Sharp中使用RSA对128个字节的字节数组进行签名

Dan*_*iel 3 c# cryptography rsa

我对密码学是完全陌生的,我需要使用C Sharp生成的RSA密钥对128字节的字节数组进行签名。密钥必须是1024位。

我发现了一些如何在C Sharp中使用RSA的示例,而我目前正在尝试使用的代码是:

public static void AssignParameter()
{
    const int PROVIDER_RSA_FULL = 1;
    const string CONTAINER_NAME = "SpiderContainer";
    CspParameters cspParams;
    cspParams = new CspParameters(PROVIDER_RSA_FULL);
    cspParams.KeyContainerName = CONTAINER_NAME;
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
    cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
    rsa = new RSACryptoServiceProvider(cspParams);
    rsa.KeySize = 1024;
}

public static string EncryptData(string data2Encrypt)
{
    AssignParameter();
    StreamReader reader = new StreamReader(path + "publickey.xml");
    string publicOnlyKeyXML = reader.ReadToEnd();
    rsa.FromXmlString(publicOnlyKeyXML);
    reader.Close();

    //read plaintext, encrypt it to ciphertext

    byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data2Encrypt);
    byte[] cipherbytes = rsa.Encrypt(plainbytes, false);
    return Convert.ToBase64String(cipherbytes);
}
Run Code Online (Sandbox Code Playgroud)

这段代码适用于小的字符串(以及较短的字节数组),但是当我尝试使用128个字符的字符串时,我收到一条错误消息:未处理CryptographicException:错误的长度(好的,它可能无法准确地说出“错误的长度”,我收到的是丹麦文错误,那就是“ Forkertlængde”,它直接翻译成“长度错误”。

谁能告诉我如何在C Sharp中使用1024位的RSA密钥加密128字节的字节数组?

在此先感谢,LordJesus

编辑:

好的,请澄清一下:我有一条消息,使用SHA-256从中进行哈希处理。这给出了一个32字节的数组。该数组使用自定义填充进行填充,因此最终为128字节数组。然后,应该使用我的私钥对这个填充的哈希签名,以便接收者可以使用我的公钥来验证接收到的消息与发送的消息相同。可以用1024位的密钥完成此操作吗?

Tho*_*nin 5

如果要签名,则不想加密。签名和加密是不同的算法。众所周知,有一种称为RSA的签名算法和一种也称为RSA的著名非对称加密算法,而且这种签名算法最初(在很多地方仍然使用)表示为“您使用私钥”。这简直令人困惑。

在RSA加密中,必须使用PKCS#1(RSA标准)描述的“ Type 2 padding”填充要加密的数据(使用公共密钥),然后将结果(长度与模数相同)通过作为RSA核心的模块化指数处理(核心,但是RSA 不仅是模块化指数;填充对于安全性非常重要)。

签名时,必须对要签名的数据进行哈希处理,然后将哈希值嵌入描述刚刚使用的哈希函数的结构中,并在编码后的结构本身中填充“ Type 1 padding”(填充类型不相同)而不是加密的填充,这一点也很重要。

无论哪种方式,普通的RSA引擎都将自己执行1型或2型填充,并且大多数RSA 签名引擎也将自己处理标识所使用的哈希函数的结构。可以使用的RSA签名引擎,例如,RSACryptoServiceProvider可以使用SignHash(),它期望散列值(从SHA-256获得的32个字节,没有任何类型的封装结构或类型1填充- RSACryptoServiceProvider自行处理),或者SignData()可以期望数据签名(引擎然后也进行哈希计算)。

综上所述,如果您自己进行填充,那么您做错了。如果您曾经Encrypt()计算签名,那么您做错了。