填充无效,无法删除-在C#中解密在Java中完成加密

问题描述

Java code

public String encrypt(String key,String value) {
    try {
      String initVector = "RgUkXp2s5v8y/B?E";
      IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
      SecretKeySpec skeySpec = new SecretKeySpec(hashKey(key),"AES");
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
      cipher.init(1,skeySpec,iv);
      byte[] encrypted = cipher.doFinal(value.getBytes());
      return Base64.getEncoder().encodetoString(encrypted);
    } catch (Exception ex) {
      ex.printstacktrace();
      return null;
    } 
  }
  
  private byte[] hashKey(String keyvalue) throws NoSuchAlgorithmException,UnsupportedEncodingException {
    byte[] key = keyvalue.getBytes("UTF-8");
    MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
    key = messageDigest.digest(key);
    return Arrays.copyOf(key,16);
  }



public static String decrypt(byte[] key,String encrypted)
{
    try
    {
        String initVector = "RgUkXp2s5v8y/B?E";
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key,"AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(2,iv);
        byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));
        return new String(original);
    }
    catch (Exception ex)
    {
        Logger.getLogger("Decryption ").log(Level.SEVERE,"Exception processing decryption " + ex.getMessage());
        return null;
    }
}

String encryptedLicense = ENCRYPT.encrypt(string_key,stringToEncrypt);




converted c# code

   public static byte[] getDefaultKey()
{
    return DecryptUtil.hashKey(DecryptUtil.getUniqueIdentifier());
}


private static byte[] hashKey(string keyvalue)
{
    try
    {
        var sha1 = SHA1Managed.Create();
        byte[] inputBytes = Encoding.UTF8.GetBytes(keyvalue);
        byte[] outputBytes = sha1.ComputeHash(inputBytes);
        return outputBytes;
       
    }
    catch (Exception ex)
    {
        ErrorLogger.WritetoFile("hashKey " + ex.Message.ToString());
    }
    return null;
}

public static string Decrypt_License(string encryptedText,byte[] key)
{
    string initVector = "RgUkXp2s5v8y/B?E";
                var ivBytes = Encoding.UTF8.GetBytes(initVector);
                var keyBytes = new byte[16];
                Array.copy(key,keyBytes,Math.Min(keyBytes.Length,key.Length));
                string plaintext = null;
                // Create AesManaged    
                using (AesManaged aes = new AesManaged())
                {
                    aes.Padding = PaddingMode.PKCS7;
                    aes.Key = keyBytes;
                    aes.IV = ivBytes;
                    aes.BlockSize = 128;
                    aes.KeySize = 128;
                    aes.Mode = CipherMode.CBC;
                     
                    ICryptoTransform decryptor = aes.CreateDecryptor(keyBytes,ivBytes);
                   
                    
                    using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(encryptedText)))
                    {
                       
                        using (CryptoStream cs = new CryptoStream(ms,decryptor,CryptoStreamMode.Read))
                        {
                               
                            using (StreamReader reader = new StreamReader(cs))
                                plaintext = reader.ReadToEnd();
                        }
                    }
                }
                return plaintext;
}

String decryptedString = DecryptUtil.Decrypt_License(hashkey(string_key),stringToDecrypt);

我正在将Java代码转换为c#,现在已经在java中完成了加密,我正在尝试解密c#中的数据。我读了PaddingMode.PKCS7和PKCS5都是一样的。是真的吗还是应该更改填充类型?

我已经使用了Java中使用的所有概念。但它不起作用。我想念什么吗?

我对Convert.FromBase64String(encryptedText)表示怀疑,因为这是他们(java)使用value.getBytes()的地方。在C#中等效的getBytes()是Convert.FromBase64String()吗?他们会产生相同的结果吗?

Java hashkey()方法和C#hashkey方法给出不同的结果。如何将它们比较为byte []?

如果我将Convert.FromBase64String()更改为Encoding.UTF8.GetBytes(),则会抛出“要解密的数据长度是无效的AES C#”错误

这是我的加密文本 wJZESOEPNb66FbnpB8DqmwLcyosxGOjzgPKa9 + 7 / VUatEFxSs1YqS28HHU26EmCcZDo7otE5PvX / qIpgQgTrhlCHgUJBb0 + qd522 / 1egYoisE48ZL8X3cwCNx1AOVYJ0T2VOLB + J3HDWK4HOJfgm2CqbQpep0ioOTgNKQA0SF3SRmF92MGbf7wjUBA8WGdeUiIKRX9Lm / x6mUUuXHEIrCHbZOqDZvo2xR9zndIzwT / FfgLsQbJQjRjZPg7urfWLpUt6drbYcPFm3KgTmSrsRhzk15P6mw3GNO + 3BmqBIndKmzi8blQqG8YFXVW8wiaurCm0jVcX5kwdU1PO1ktHSXQ ==

用于加密的秘密密钥 BFEBFBFF000306D4

解决方法

我对c#aes和hashKey使用了自己的解密方法,并且我知道它们正在工作:-)。

将这些数据作为Java加密的输入:

String string_key = "mySecretKey";
String stringToEncrypt = "The quick brown fox jumps over the lazy dog";

我得到了

encryptedLicense: lrgzfdMTetZKeAFlCAbCDBL4VhtpVGdhTESl9QNgs5b0KOWke1CnKQQf+xmB+/mK

使用此字符串和给C#的给定string_key进行输出:

plaintext expect : The quick brown fox jumps over the lazy dog
plaintext from C#: The quick brown fox jumps over the lazy dog

安全警告:此代码使用固定的加密密钥和固定的初始化向量,从而使 完全加密不安全。该代码没有适当的异常处理,仅用于教育目的。

C#代码:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class Program {
    public static void Main() {
        Console.WriteLine("Padding is invalid and cannot be removed - decryption in c# (encryption done in java)");

        string plaintextExpected = "The quick brown fox jumps over the lazy dog";
        string encryptedLicense = "lrgzfdMTetZKeAFlCAbCDBL4VhtpVGdhTESl9QNgs5b0KOWke1CnKQQf+xmB+/mK";
        string string_key = "mySecretKey";
        string plaintext = "";

        // decryption
        plaintext = decryptFromBase64(hashKey(string_key),encryptedLicense);
        Console.WriteLine("plaintext expect : " + plaintextExpected);
        Console.WriteLine("plaintext from C#: " + plaintext);
    }

    public static byte[] hashKey(string value)
    {
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
        SHA1 sha = new SHA1CryptoServiceProvider();
        byte[] sha1Hash = sha.ComputeHash(bytes);
        byte[] sha1HashLength = new byte[16];
        Array.Copy(sha1Hash,sha1HashLength,16);
        return sha1HashLength;
    }

    static string decryptFromBase64(byte[] key,string data) {
        string decryptedtext;
        using(Aes aesAlg = Aes.Create()) {
            aesAlg.Key = key;
            string initVector = "RgUkXp2s5v8y/B?E";
            byte[] IV = Encoding.UTF8.GetBytes(initVector);
            byte[] cipherText = Convert.FromBase64String(data);
            aesAlg.IV = IV;
            aesAlg.Mode = CipherMode.CBC;
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key,aesAlg.IV);
            using(var msDecrypt = new MemoryStream(cipherText)) {
                using(var csDecrypt = new CryptoStream(msDecrypt,decryptor,CryptoStreamMode.Read)) {
                    using(var srDecrypt = new StreamReader(csDecrypt)) {
                        decryptedtext = srDecrypt.ReadToEnd();
                    }
                }
            }
        }
        return decryptedtext;
    }
}

修改1: 在我的Java代码中,我更改了以下行:

//String string_key = "mySecretKey";
String string_key = "BFEBFBFF000306D4";

得到结果:

encryptedLicense: 7QWzpg/rVE6AhmcGphFT9uswU8hgKjG3i9NHJHCn/fKITYNIljOb28+cbh5y5JEA

按如下所示更改我的C#代码:

//string encryptedLicense = "lrgzfdMTetZKeAFlCAbCDBL4VhtpVGdhTESl9QNgs5b0KOWke1CnKQQf+xmB+/mK";
string encryptedLicense = "7QWzpg/rVE6AhmcGphFT9uswU8hgKjG3i9NHJHCn/fKITYNIljOb28+cbh5y5JEA";
//string string_key = "mySecretKey";
string string_key = "BFEBFBFF000306D4";

得到结果:

plaintext expect : The quick brown fox jumps over the lazy dog
plaintext from C#: The quick brown fox jumps over the lazy dog

一切正常。