简体   繁体   中英

Bouncy Castle Encrypt in Java Decrypt in .Net

I used the following to encrypt a string using a password

    static String algorithm = "PBEWITHSHA256AND128BITAES-CBC-BC";
static byte[] salt = "b9v4n38s".getBytes(StandardCharsets.UTF_8);
static int derivedKeyLength = 128;
static int iterations = 20000;

public static byte[] encrypt(String plainText, String password) throws NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException, NoSuchAlgorithmException {
    Security.addProvider(new BouncyCastleProvider());
    KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength);
    SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm);
    SecretKey key = f.generateSecret(spec);
    Cipher cipher = Cipher.getInstance(algorithm);
    cipher.init(Cipher.ENCRYPT_MODE, key);   
    byte[] text = plainText.getBytes(StandardCharsets.UTF_8);         
    byte[] encrypted = cipher.doFinal(text);
    return encrypted;
}

The result of this is base64 encoded and sent as arg[0] to.Net (arg[1] is the same password). Now I'm trying to decrypt that string in.Net with this code

    private static string Decrypt(string[] args)
    {
        int derivedKeyLength = 128;
        int iterations = 20000;
        string algorithm = "PBEWITHSHA256AND128BITAES-CBC-BC";
        byte[] salt = Encoding.UTF8.GetBytes("b9v4n38s");

        PbeParametersGenerator pGen = new Pkcs12ParametersGenerator(new Sha256Digest());
        pGen.Init(Encoding.UTF8.GetBytes(args[1]), salt, iterations);
        ICipherParameters par = pGen.GenerateDerivedParameters("AES256", derivedKeyLength);
        IBufferedCipher c = CipherUtilities.GetCipher(algorithm);
        c.Init(false, par);
        var input = Convert.FromBase64String(args[0]);
        byte[] enc = c.DoFinal(input);
        var decoded = Encoding.UTF8.GetString(enc);
        return decoded;
    }

Unfortunately it fails on DoFinal with message Org.BouncyCastle.Crypto.InvalidCipherTextException: 'pad block corrupted'

SecretKeyFactory.getInstance(algorithm) uses the same algorithm string as Cipher.getInstance(algorithm) in java but if I try pGen.GenerateDerivedParameters(algorithm, derivedKeyLength); in.Net it throws Org.BouncyCastle.Security.SecurityUtilityException: 'Algorithm PBEWITHSHA256AND128BITAES-CBC-BC not recognised.'

I'm not set on this algorithm, just looking for a way to encrypt a string in Java and decrypt it in.Net.

A possible C#/BC code to decrypt a ciphertext generated with the posted Java code is:

using System;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
...
private static string algorithm = "PBEWITHSHA256AND128BITAES-CBC-BC";
private static byte[] salt = Encoding.UTF8.GetBytes("b9v4n38s");
private static int iterations = 20000;

public static string Decrypt(string ciphertextB64, string password)
{
    IBufferedCipher cipher = CipherUtilities.GetCipher(algorithm);
    Asn1Encodable algParams = PbeUtilities.GenerateAlgorithmParameters(algorithm, salt, iterations);
    ICipherParameters cipherParams = PbeUtilities.GenerateCipherParameters(algorithm, password.ToCharArray(), algParams);
    cipher.Init(false, cipherParams);

    byte[] cipherBytes = Convert.FromBase64String(ciphertextB64);
    byte[] decrypted = cipher.DoFinal(cipherBytes);

    return Encoding.UTF8.GetString(decrypted);
}

Test:

string decrypted = Decrypt("mBy4YwAvUpvoSJhzBnpOCJw2kCayvdYfLJ/12x0BgUKh5m5bvArSheMMs2U5rYyE", "MyPassword");
Console.WriteLine(decrypted); // The quick brown fox jumps over the lazy dog

where the ciphertext was generated with the Java code using the password MyPassword .

Please note that a static salt is generally insecure (except for testing purposes of course).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM