c# RSA用私钥加密

本文关键字:加密 私钥 RSA | 更新日期: 2023-09-27 18:14:52

公钥加密私钥解密成功:

c#公钥加密(成功)

   public string EncryptData(string data) {
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(xml); //public key
        var cipher = rsa.Encrypt(Encoding.UTF8.GetBytes(data), false);
        return Convert.ToBase64String(cipher );
    }

Java私钥解密(成功)

public static void decrypt() throws Exception{
    byte[] modulusBytes = Base64.getDecoder().decode(mod);
    byte[] dByte = Base64.getDecoder().decode(d);
    BigInteger modulus = new BigInteger(1, (modulusBytes));
    BigInteger exponent = new BigInteger(1, (dByte));
    RSAPrivateKeySpec rsaPrivKey = new RSAPrivateKeySpec(modulus, exponent);
    KeyFactory fact = KeyFactory.getInstance("RSA");
    PrivateKey privKey = fact.generatePrivate(rsaPrivKey);
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, privKey);
    byte[] cipherData = Base64.getDecoder().decode(cipherByte);
    byte[] plainBytes = cipher.doFinal(cipherData);

    System.out.println(new String(plainBytes));
} 

问题在这里

当c#使用私钥加密,java使用公钥解密时,出现填充错误:

c#私钥加密(Fail)

public stringEncryptData(string data) {
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(xml); //private key
        var cypher = rsa.Encrypt(Encoding.UTF8.GetBytes(data), false);
        return  Convert.ToBase64String(cypher);
    }

java decryption with public key (Fail)

public static void decryptPublic() throws Exception{
    byte[] modulusBytes = Base64.getDecoder().decode(mod);
    byte[] expBytes = Base64.getDecoder().decode(exp);
    BigInteger modulus = new BigInteger(1, (modulusBytes));
    BigInteger exponent = new BigInteger(1, (expBytes));
    RSAPublicKeySpec pubKey = new RSAPublicKeySpec(modulus, exponent);
    KeyFactory fact = KeyFactory.getInstance("RSA");
    PublicKey publicKey = fact.generatePublic(pubKey);
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, publicKey );

    byte[] cipherData = Base64.getDecoder().decode(cipherByte);
    byte[] plainBytes = cipher.doFinal(cipherData);
    System.out.println(new String(plainBytes));
} 

我明白公钥应该用来做加密和私钥解密。但是在我的情况下,我需要将公钥发送给多个客户端,以便对其私钥加密的文本进行解密。文本应该是不可读的,除了客户端。谁能看到我的代码有什么问题,或建议一个更好的解决方案,我的问题。

c# RSA用私钥加密

RSA加密只有在使用(安全的)填充方案时才是安全的。RSA加密方案已由RSA实验室(现在是EMC2的一部分)在pkcs# 1标准中指定。这些已经被复制到RFC中,例如RFC 3447:公钥加密标准(PKCS) #1: RSA加密规范版本2.1。

在本文档中,加密方案由以下部分组成加密操作和解密操作,其中加密操作从带有a的消息生成密文接收方的RSA公钥,通过解密操作恢复接收方的RSA公钥使用接收者对应的RSA从密文中获取消息私钥 .

所以私钥加密是一个未定义的操作。


那么现在该怎么办呢:

  • 安全地分发私钥而不是公钥
  • 生成密钥对并安全地将公钥传输给发送方
  • 如果您需要认证/完整性而不是机密性,请使用签名生成而不是加密

无论您做什么,都要读入公钥基础设施(PKI)。

这是一个很复杂的问题,你需要先理解它才能应用它。

使用私钥加密/使用公钥解密是RSA中的合法操作,但是不是用于保护数据,而是用于验证数据的来源及其完整性。在这种情况下,加密操作通常被称为"签名"。

使用私钥加密来保护你所描述的数据是不安全的,所以它不容易做到的事实很可能是故意的,旨在防止错误使用算法。

按照评论中建议的那样将您的私钥分发给客户端也是不明智的,因为您无法控制他们可能将密钥传递给谁(意外或其他)。

如果您希望加密数据,以便可以由多个不同的方解密,那么您应该让每个方都为您提供自己的公钥,并使用该公钥为每个客户端分别加密数据。