Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# RSA.NET加密Java解密_C#_Java_Security_Cryptography - Fatal编程技术网

C# RSA.NET加密Java解密

C# RSA.NET加密Java解密,c#,java,security,cryptography,C#,Java,Security,Cryptography,我正在尝试使用RSA算法在.NET中加密字符串,并在Java中解密结果。目前,我可以做相反的事情(用Java加密,用.NET解密)。 在这里,我有我的实际工作的代码(JAVA加密): 和(.NET解密) 根据您的要求,这里有一些代码片段。RSA密钥来自x509证书 Java RSA/AES: // symmetric algorithm for data encryption final String ALGORITHM = "AES"; // Padding for symmetric alg

我正在尝试使用RSA算法在.NET中加密字符串,并在Java中解密结果。目前,我可以做相反的事情(用Java加密,用.NET解密)。 在这里,我有我的实际工作的代码(JAVA加密):

和(.NET解密)


根据您的要求,这里有一些代码片段。RSA密钥来自x509证书

Java RSA/AES:

// symmetric algorithm for data encryption
final String ALGORITHM = "AES";
// Padding for symmetric algorithm
final String PADDING_MODE = "/CBC/PKCS5Padding";
// character encoding
final String CHAR_ENCODING = "UTF-8";
// provider for the crypto
final String CRYPTO_PROVIDER = "Entrust";
// RSA algorithm used to encrypt symmetric key
final String RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";
// symmetric key size (128, 192, 256) if using 192+ you must have the Java
// Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
// installed
int AES_KEY_SIZE = 256;

private byte[] encryptWithRSA(byte[] aesKey, X509Certificate cert)
        throws NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    // get the public key from the encryption certificate to encrypt with
    PublicKey pubKey = cert.getPublicKey();

    // get an instance of the RSA Cipher
    Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM);

    // set the cipher to use the public key
    rsaCipher.init(Cipher.ENCRYPT_MODE, pubKey);

    // encrypt the aesKey
    return rsaCipher.doFinal(aesKey);
}

private AESEncryptedContents encryptWithAes(byte[] dataToEncrypt)
        throws NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException,
        BadPaddingException, NoSuchProviderException {
    // get the symmetric key generator
    KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);
    keyGen.init(AES_KEY_SIZE); // set the key size

    // generate the key
    SecretKey skey = keyGen.generateKey();

    // convert to binary
    byte[] rawAesKey = skey.getEncoded();

    // initialize the secret key with the appropriate algorithm
    SecretKeySpec skeySpec = new SecretKeySpec(rawAesKey, ALGORITHM);

    // get an instance of the symmetric cipher
    Cipher aesCipher = Cipher.getInstance(ALGORITHM + PADDING_MODE,
            CRYPTO_PROVIDER);

    // set it to encrypt mode, with the generated key
    aesCipher.init(Cipher.ENCRYPT_MODE, skeySpec);

    // get the initialization vector being used (to be returned)
    byte[] aesIV = aesCipher.getIV();

    // encrypt the data
    byte[] encryptedData = aesCipher.doFinal(dataToEncrypt);

    // package the aes key, IV, and encrypted data and return them
    return new AESEncryptedContents(rawAesKey, aesIV, encryptedData);
}

private byte[] decryptWithAES(byte[] aesKey, byte[] aesIV,
        byte[] encryptedData) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException,
        InvalidAlgorithmParameterException, IllegalBlockSizeException,
        BadPaddingException, UnsupportedEncodingException,
        NoSuchProviderException {
    // initialize the secret key with the appropriate algorithm
    SecretKeySpec skeySpec = new SecretKeySpec(aesKey, ALGORITHM);

    // get an instance of the symmetric cipher
    Cipher aesCipher = Cipher.getInstance(ALGORITHM + PADDING_MODE,
            CRYPTO_PROVIDER);

    // set it to decrypt mode with the AES key, and IV
    aesCipher.init(Cipher.DECRYPT_MODE, skeySpec,
            new IvParameterSpec(aesIV));

    // decrypt and return the data
    byte[] decryptedData = aesCipher.doFinal(encryptedData);

    return decryptedData;
}

private byte[] decryptWithRSA(byte[] encryptedAesKey, PrivateKey privKey)
        throws IllegalBlockSizeException, BadPaddingException,
        InvalidKeyException, NoSuchAlgorithmException,
        NoSuchPaddingException, NoSuchProviderException {
    // get an instance of the RSA Cipher
    Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM, CRYPTO_PROVIDER);

    // set the cipher to use the public key
    rsaCipher.init(Cipher.DECRYPT_MODE, privKey);

    // encrypt the aesKey
    return rsaCipher.doFinal(encryptedAesKey);
}
public byte[] encryptData(byte[] data, out byte[] encryptedAesKey, out byte[] aesIV) {
    if (data == null)
        throw new ArgumentNullException("data");

    byte[] encryptedData; // data to return

    // begin AES key generation
    RijndaelManaged aesAlg = new RijndaelManaged();
    aesAlg.KeySize = AES_KEY_SIZE;
    aesAlg.GenerateKey();
    aesAlg.GenerateIV();
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Padding = PaddingMode.PKCS7;

    // aes Key to be encrypted
    byte[] aesKey = aesAlg.Key;

    // aes IV that is passed back by reference
    aesIV = aesAlg.IV;

    //get a new RSA crypto service provider to encrypt the AES key with the certificates public key
    using (RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider())
    {
        //add the certificates public key to the RSA crypto provider
        rsaCSP.FromXmlString(encryptionCertificate.PublicKey.Key.ToXmlString(false));

        //encrypt AES key with RSA Public key
        //passed back by reference
        encryptedAesKey = rsaCSP.Encrypt(aesKey, false);

        //get an aes encryptor instance
        ICryptoTransform aesEncryptor = aesAlg.CreateEncryptor();

        encryptedData = encryptWithAes(aesEncryptor, data);
    }

    if (encryptedData == null)
        throw new CryptographicException(
                "Fatal error while encrypting with AES");

    return encryptedData;
}

private byte[] encryptWithAes(ICryptoTransform aesEncryptor, byte[] data) {
    MemoryStream memStream = null; // stream to write encrypted data to
    CryptoStream cryptoStream = null; // crypto stream to encrypted data

    try {
        memStream = new MemoryStream();

        // initiate crypto stream telling it to write the encrypted data to
        // the memory stream
        cryptoStream = new CryptoStream(memStream, aesEncryptor,
                CryptoStreamMode.Write);

        // write the data to the memory stream
        cryptoStream.Write(data, 0, data.Length);
    } catch (Exception ee) {
        // rethrow
        throw new Exception("Error while encrypting with AES: ", ee);
    } finally {
        // close 'em
        if (cryptoStream != null)
            cryptoStream.Close();
        if (memStream != null)
            memStream.Close();
    }

    // return the encrypted data
    return memStream.ToArray();
}
C#Net:

// symmetric algorithm for data encryption
final String ALGORITHM = "AES";
// Padding for symmetric algorithm
final String PADDING_MODE = "/CBC/PKCS5Padding";
// character encoding
final String CHAR_ENCODING = "UTF-8";
// provider for the crypto
final String CRYPTO_PROVIDER = "Entrust";
// RSA algorithm used to encrypt symmetric key
final String RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";
// symmetric key size (128, 192, 256) if using 192+ you must have the Java
// Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
// installed
int AES_KEY_SIZE = 256;

private byte[] encryptWithRSA(byte[] aesKey, X509Certificate cert)
        throws NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    // get the public key from the encryption certificate to encrypt with
    PublicKey pubKey = cert.getPublicKey();

    // get an instance of the RSA Cipher
    Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM);

    // set the cipher to use the public key
    rsaCipher.init(Cipher.ENCRYPT_MODE, pubKey);

    // encrypt the aesKey
    return rsaCipher.doFinal(aesKey);
}

private AESEncryptedContents encryptWithAes(byte[] dataToEncrypt)
        throws NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException,
        BadPaddingException, NoSuchProviderException {
    // get the symmetric key generator
    KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);
    keyGen.init(AES_KEY_SIZE); // set the key size

    // generate the key
    SecretKey skey = keyGen.generateKey();

    // convert to binary
    byte[] rawAesKey = skey.getEncoded();

    // initialize the secret key with the appropriate algorithm
    SecretKeySpec skeySpec = new SecretKeySpec(rawAesKey, ALGORITHM);

    // get an instance of the symmetric cipher
    Cipher aesCipher = Cipher.getInstance(ALGORITHM + PADDING_MODE,
            CRYPTO_PROVIDER);

    // set it to encrypt mode, with the generated key
    aesCipher.init(Cipher.ENCRYPT_MODE, skeySpec);

    // get the initialization vector being used (to be returned)
    byte[] aesIV = aesCipher.getIV();

    // encrypt the data
    byte[] encryptedData = aesCipher.doFinal(dataToEncrypt);

    // package the aes key, IV, and encrypted data and return them
    return new AESEncryptedContents(rawAesKey, aesIV, encryptedData);
}

private byte[] decryptWithAES(byte[] aesKey, byte[] aesIV,
        byte[] encryptedData) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException,
        InvalidAlgorithmParameterException, IllegalBlockSizeException,
        BadPaddingException, UnsupportedEncodingException,
        NoSuchProviderException {
    // initialize the secret key with the appropriate algorithm
    SecretKeySpec skeySpec = new SecretKeySpec(aesKey, ALGORITHM);

    // get an instance of the symmetric cipher
    Cipher aesCipher = Cipher.getInstance(ALGORITHM + PADDING_MODE,
            CRYPTO_PROVIDER);

    // set it to decrypt mode with the AES key, and IV
    aesCipher.init(Cipher.DECRYPT_MODE, skeySpec,
            new IvParameterSpec(aesIV));

    // decrypt and return the data
    byte[] decryptedData = aesCipher.doFinal(encryptedData);

    return decryptedData;
}

private byte[] decryptWithRSA(byte[] encryptedAesKey, PrivateKey privKey)
        throws IllegalBlockSizeException, BadPaddingException,
        InvalidKeyException, NoSuchAlgorithmException,
        NoSuchPaddingException, NoSuchProviderException {
    // get an instance of the RSA Cipher
    Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM, CRYPTO_PROVIDER);

    // set the cipher to use the public key
    rsaCipher.init(Cipher.DECRYPT_MODE, privKey);

    // encrypt the aesKey
    return rsaCipher.doFinal(encryptedAesKey);
}
public byte[] encryptData(byte[] data, out byte[] encryptedAesKey, out byte[] aesIV) {
    if (data == null)
        throw new ArgumentNullException("data");

    byte[] encryptedData; // data to return

    // begin AES key generation
    RijndaelManaged aesAlg = new RijndaelManaged();
    aesAlg.KeySize = AES_KEY_SIZE;
    aesAlg.GenerateKey();
    aesAlg.GenerateIV();
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Padding = PaddingMode.PKCS7;

    // aes Key to be encrypted
    byte[] aesKey = aesAlg.Key;

    // aes IV that is passed back by reference
    aesIV = aesAlg.IV;

    //get a new RSA crypto service provider to encrypt the AES key with the certificates public key
    using (RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider())
    {
        //add the certificates public key to the RSA crypto provider
        rsaCSP.FromXmlString(encryptionCertificate.PublicKey.Key.ToXmlString(false));

        //encrypt AES key with RSA Public key
        //passed back by reference
        encryptedAesKey = rsaCSP.Encrypt(aesKey, false);

        //get an aes encryptor instance
        ICryptoTransform aesEncryptor = aesAlg.CreateEncryptor();

        encryptedData = encryptWithAes(aesEncryptor, data);
    }

    if (encryptedData == null)
        throw new CryptographicException(
                "Fatal error while encrypting with AES");

    return encryptedData;
}

private byte[] encryptWithAes(ICryptoTransform aesEncryptor, byte[] data) {
    MemoryStream memStream = null; // stream to write encrypted data to
    CryptoStream cryptoStream = null; // crypto stream to encrypted data

    try {
        memStream = new MemoryStream();

        // initiate crypto stream telling it to write the encrypted data to
        // the memory stream
        cryptoStream = new CryptoStream(memStream, aesEncryptor,
                CryptoStreamMode.Write);

        // write the data to the memory stream
        cryptoStream.Write(data, 0, data.Length);
    } catch (Exception ee) {
        // rethrow
        throw new Exception("Error while encrypting with AES: ", ee);
    } finally {
        // close 'em
        if (cryptoStream != null)
            cryptoStream.Close();
        if (memStream != null)
            memStream.Close();
    }

    // return the encrypted data
    return memStream.ToArray();
}

Java解密代码的最后几行没有意义。这些线路是:

byte[] base64String = Base64.decode(encodedString);
byte[] plainBytes = new String(base64String).getBytes("UTF-8");
byte[] cipherData = cipher.doFinal(plainBytes);

System.out.println(cipherData);
return cipherData.toString();
您必须颠倒在.NET中用于加密的步骤顺序。首先,您应该对编码的字符串进行Base64解码以获得密码字节。您这样做了,但将结果错误标记为
base64String
。您可能应该调用此结果
cipherData
。其次,您需要解密密码数据以获得纯文本。第三,您应该使用双参数字符串构造函数从纯字节创建一个字符串,第二个参数为字符集。下面是代码应该是什么样子,或者与之相近

byte[] cipherData = Base64.decode(encodedString);
byte[] plainBytes = cipher.doFinal(cipherData);

return new String(plainBytes, "UTF-8");
最后,在Java中,每个对象都有一个toString()方法,但它并不总是做您想做的事情。对于数组,toString()方法只返回该数组的对象id表示形式,类似于内存地址的JVM

编辑:


我没有注意到您在解密代码中也使用了错误的密钥。您使用的是RSA公钥,但您必须使用RSA私钥。

这是我昨天无法发布的答案,与我发布的第一个答案相关


嗯,我已经测试了代码,我有一些问题。我一直试图不改变任何事情,除非它是完全必要的。 首先,我在这里得到一个错误:

Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM, CRYPTO_PROVIDER);
无法识别“委托”加密提供程序。。。所以我只留下了第一个参数。然后我得到这个错误:

javax.crypto.BadPaddingException: Data must start with zero
我尝试了一个用.NET编写的Web服务,它总是返回字节数组。也许在翻译过程中出现了一些问题。我知道我必须使用Base64数字,并且(如果我不使用AES),我必须将字符串分成128字节大小的片段(受RSA密钥限制)。 我仍在研究这个问题,以了解为什么我可以在Java中加密,在.NET中解密,而不是相反


再次感谢你的帮助

给我们一些堆叠痕迹。是否指定相同的填充方案?我可以在.Net中加密,在Java中解密,反之亦然,没问题。虽然我使用PKCS5Padding(Java)和PKCS7(.Net)并且没有硬编码密钥,但我无法给出任何跟踪,因为我得到的错误是不同的(正如我所说的密钥大小,将异常填充为:javax.crypto.baddingexception:数据必须以零开始)。。。我可以发布不起作用的代码,但我现在正在处理它。如果你能告诉我你是怎么做的,我将非常感激,因为在接下来的几天里解决这个问题对我来说非常重要……非常感谢Petey!我将尝试这段代码……我希望它能工作,并且不会给我任何字节[]到字符串转换的问题。我将尝试调整它(我不使用证书或AES),我将在尝试后尽快发布。再次感谢@Reixons,没问题,如果我能帮忙,请告诉我。你要加密什么?如果它比你的RSA密钥长度长,你应该使用AES+RSA。好吧,我已经测试了代码,我有一些问题。我得到:javax.crypto.BadPaddingException:数据必须从零开始,我将在2h内尝试更好地描述它。我现在没有足够的声誉去做这件事!!:(我使用的是私钥,但为了生成私钥,我使用的模和指数与生成公钥的模和指数相同……对吗?你是对的,我的第一个代码的问题是,我也使用指数生成私钥,我应该使用“D”密钥的一部分。现在它工作了。谢谢大家!!我正在做一些非常类似的事情,但由于解密,我得到了一个空输入缓冲区:java.lang.IllegalArgumentException:空输入缓冲区在代码中的某个地方。我打印了我的私钥,它似乎是这样的:Sun RSA私钥,1024位模数:1711700308465724595132409320104296254162648817557411074899862199275295356525279994079227私人指数:99473302025154625525526734732044759431077578773125948154824200106840847929746840991292557544482314157718836061315811212481我取出了它的一部分,因为它太长了。知道为什么会发生这种情况吗我注意到在做了byte[]cipherData=Base64.decode(encodedString);cipherData为null。为什么会这样?基本上:返回新字符串(cipherData,“UTF-8”);返回null,现在我得到的是:数据必须以零开始:javax.crypto.BadPaddingException:数据必须以零开始
Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM, CRYPTO_PROVIDER);
javax.crypto.BadPaddingException: Data must start with zero