【问题标题】:Bouncy Castle Encrypt in Java Decrypt in .NetJava 中的 Bouncy Castle 加密 .Net 中的解密
【发布时间】:2021-08-03 04:03:29
【问题描述】:

我使用以下方法使用密码加密字符串

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

结果是 base64 编码并作为 arg[0] 发送到 .Net(arg[1] 是相同的密码)。现在我正在尝试使用此代码在 .Net 中解密该字符串

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

不幸的是,它在 DoFinal 上失败并显示消息 Org.BouncyCastle.Crypto.InvalidCipherTextException: 'pad block corrupted'

SecretKeyFactory.getInstance(algorithm) 使用与 java 中的 Cipher.getInstance(algorithm) 相同的算法字符串,但如果我在 .Net 中尝试 pGen.GenerateDerivedParameters(algorithm, derivedKeyLength); 它会抛出 Org.BouncyCastle.Security.SecurityUtilityException: 'Algorithm PBEWITHSHA256AND128BITAES-CBC-BC not recognised.'

我没有设置这个算法,只是在寻找一种在Java中加密字符串并在.Net中解密的方法。

【问题讨论】:

    标签: java c# encryption bouncycastle


    【解决方案1】:

    用于解密使用发布的 Java 代码生成的密文的可能 C#/BC 代码是:

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

    测试:

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

    其中密文是使用密码 MyPassword 使用 Java 代码生成的。

    请注意,静态盐通常是不安全的(当然测试目的除外)。

    【讨论】:

      猜你喜欢
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      • 2022-09-29
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      相关资源
      最近更新 更多