Saya menggunakan yang berikut ini untuk mengenkripsi string menggunakan kata sandi

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

Hasilnya adalah base64 dikodekan dan dikirim sebagai arg[0] ke .Net (arg[1] adalah kata sandi yang sama). Sekarang saya mencoba mendekripsi string itu di .Net dengan kode ini

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

Sayangnya gagal di DoFinal dengan pesan Org.BouncyCastle.Crypto.InvalidCipherTextException: 'pad block corrupted'

SecretKeyFactory.getInstance(algorithm) menggunakan string algoritma yang sama dengan Cipher.getInstance(algorithm) di java tetapi jika saya mencoba pGen.GenerateDerivedParameters(algorithm, derivedKeyLength); di .Net itu melempar Org.BouncyCastle.Security.SecurityUtilityException: 'Algorithm PBEWITHSHA256AND128BITAES-CBC-BC not recognised.'

Saya tidak menggunakan algoritme ini, hanya mencari cara untuk mengenkripsi string di Java dan mendekripsinya di .Net.

1
Adam 12 Mei 2021, 22:03

1 menjawab

Jawaban Terbaik

Kemungkinan kode C#/BC untuk mendekripsi ciphertext yang dihasilkan dengan kode Java yang diposting adalah:

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

Uji:

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

Di mana ciphertext dibuat dengan kode Java menggunakan sandi MyPassword.

Harap dicatat bahwa garam statis umumnya tidak aman (kecuali untuk tujuan pengujian tentu saja).

1
Topaco 12 Mei 2021, 23:08