c#RSA使用私钥加密

时间:2015-09-28 05:47:16

标签: java c# encryption cryptography rsa

使用公钥加密并使用私钥解密时,加密和解密成功:

使用公钥进行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#使用私钥加密并且使用公钥解密时,会发生错误填充错误:

使用私钥进行C#加密(失败)

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解密(失败)

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

我理解公钥应该用于加密和私钥进行解密。但在我的情况下,我需要向多个客户端发送公钥,以便对通过其私钥加密的文本进行解密。除客户端外,其他人不能读取文本。 任何人都可以看到我的代码有什么问题,或建议更好地解决我的问题。

2 个答案:

答案 0 :(得分:1)

只有在使用(安全)填充方案时,RSA加密才是安全的。 RSA实验室(现为EMC 2 的一部分)已在PKCS#1标准中规定了RSA加密方案。这些已被复制到RFC中,例如RFC 3447: Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1

  

出于本文档的目的,加密方案包括      加密操作和解密操作,其中      加密操作会根据消息生成密文      收件人的RSA公钥解密操作恢复      来自密文的消息与收件人的相应RSA      私钥

因此使用私钥进行加密是一种未定义的操作。

那么现在该做什么:

  • 安全地分发私钥而非公钥
  • 生成密钥对,安全地将公钥传输给发件人
  • 如果您需要身份验证/完整性而非机密性,请使用签名生成而不是加密

而且,无论您做什么,请阅读公钥基础结构(PKI)。在您申请之前,您需要了解它是一个非常紧张的主题。

答案 1 :(得分:-1)

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

在您描述时使用私钥加密来保护数据是不安全的,因此不容易完成这一事实可能是故意的,并且旨在防止错误使用算法。

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

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