如何将Java RSA公钥移植到c#加密函数?

如何将Java RSA公钥移植到c#加密函数?,java,c#,encryption,rsa,Java,C#,Encryption,Rsa,希望在java中使用生成的RSA公钥,在c#函数中加密数据,并在java decrypt函数中解密数据 生成的Java公钥已替换为c#中的模数标记: Java解密函数: static string Encrypt(string text) { const int PROVIDER_RSA_FULL = 1; const string CONTAINER_NAME = "Tracker"; CspParameters

希望在java中使用生成的RSA公钥,在c#函数中加密数据,并在java decrypt函数中解密数据

生成的Java公钥已替换为c#中的模数标记:

Java解密函数:

  static string Encrypt(string text)
    {
        const int PROVIDER_RSA_FULL = 1;
        const string CONTAINER_NAME = "Tracker";

        CspParameters cspParams;
        cspParams = new CspParameters(PROVIDER_RSA_FULL);
        cspParams.KeyContainerName = CONTAINER_NAME;
       
        RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(512,cspParams);
        rsa1.FromXmlString(publicKey);

        byte[] textBytes = Encoding.UTF8.GetBytes(text);
        byte[] encryptedOutput = rsa1.Encrypt(textBytes, RSAEncryptionPadding.Pkcs1);
        string outputB64 = Convert.ToBase64String(encryptedOutput);

        return outputB64;
    }
static String Decrypt(String encodedString,PrivateKey privKey) {
    try {
        Cipher cipher = Cipher.getInstance(cipherInstancename);
        cipher.init(Cipher.DECRYPT_MODE, privKey);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encodedString));
        return new String(decrypted, "UTF-8");
    } catch (Exception err) {
        return err.fillInStackTrace().toString();
    }
}
第一个问题:在c#XML字符串的模标记中替换Java公钥是否正确?指数标签呢?我使用了AQAB值

第二个问题:为什么在Java中解密时出现此错误:

 javax.crypto.IllegalBlockSizeException: Data must not be longer than 64 bytes
经过一些研究我发现,这是一个普遍的错误什么原因可以使这种类型的错误

第一个问题:在模块中替换Java公钥是否正确 c#XML字符串中的标记

不!键与模数不同,但包含模数和指数。因此,在您的情况下,两者都必须根据Java中生成的密钥来确定

公钥可以以不同的格式提供。例如,在本机Java中生成的公钥通常采用X.509/SPKI格式,并且可能是
字节[]
,即采用DER编码。如果
字节[]
是Base64编码的(这对应于发布的
MFwwDQ…wEAAQ==
),并且添加了页眉------开始公钥------和页脚------结束公钥------(通常在Base64编码的正文中,每64个字符后还有一个换行符),则密钥将采用PEM编码

手动确定模数和指数的最简单方法是将PEM密钥加载到ASN.1解析器中,例如,或在合适的网站上将其直接转换为XML格式,例如

指数标签呢?我使用了AQAB值

这个问题已经用以前说过的话得到了含蓄的回答。但有一点值得注意:对于指数,通常选择值65537(十六进制编码0x010001和Base64编码AQAB)。但情况并非总是如此。因此,如果将现有密钥的指数盲目地替换为该值,则它很有可能工作,但您不能依赖它,请参见和

第二个问题:为什么在Java中解密时会出现这样的错误:javax.crypto.IllegalBlockSizeException:数据不能超过64字节

Michael Fehr的评论中已经回答了这一问题,其中包括其他重要问题(如安全性、性能和混合加密):密钥长度限制了明文的长度,使用512位密钥最多可以加密64字节

此外,应该注意的是,不仅密钥的长度,而且所使用的填充限制了明文的长度,例如PKCS#1 v1.5填充需要11字节,因此512位键的最大明文长度为64-11=53字节。在OAEP的情况下,使用的摘要确定填充所需的字节数,请参见例如。如果未使用填充(tetxbook RSA),则明文的最大长度对应于密钥长度。但实际上,出于安全考虑,必须始终使用填充



从.NET Core 3.0开始,直接支持导入X.509/SPKI密钥(DER编码)和类似格式,请参见,尤其是。在早期的.NET核心版本和.NET Framework中,这些功能不可用,但可以使用BouncyCastle。

RSA私钥/公钥加密仅限于小数据量,具体取决于密钥长度。您使用的是不安全的512位长密钥,因此一次只能加密64个字节。拥有更长的密钥将导致可以加密的更大的明文,但加密时间也会增加,因此在“现实世界”中,您将使用混合加密(生成随机AES密钥,使用此密钥加密数据,加密密钥(AES 256为32字节)使用公钥并将加密数据和加密密钥发送到Java—在Java中,使用私钥解密密钥并解密。
 javax.crypto.IllegalBlockSizeException: Data must not be longer than 64 bytes