繁体   English   中英

C# 加密为 Java 解密

[英]C# encrypt to Java Decrypt

我正在使用 C# “加密”并需要 Java “解密”方法。 I need help in java that i can't replicate C# decryption on java and it is not explicit Padding on C#, i don't know what use in java and my key size I think is different but I am not sure. 我很困惑。

知道我需要更改 Java 政策,并做到了。 并将密钥大小 JAVA 更改为 32 字节。

C#


    using System;
    using System.IO;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using Voa.Cross.Util.Extensions;

    namespace Voa.Core.Safeties
    {
        public class Security
        {
            private readonly string _defaultKey = "sjkdhfjksdhf3444KDFK4nFLFGKdsnjcnj2cmkeKDIK484dmd999sksksksUUddUZ83k030394m49jdjPuWzRk8Zq2PfnpR3YrYWSq2AaUT6meeC3tr36nTVkuudKWbDyPjhUwbwXBzkUhSPKPpSRheR49em4qJWa6YHSCjKX3K93FEMnqXhYauXwjJwbHXfPWTSdxy6ebCBPyAfqk7Uz5nrRddVjZrxWNCMZYG3PbcvPWA34ekdkd454ldnvJKl";
            private readonly int _divisionKey = 4;
            private readonly byte[] _iv = new byte[16] {0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};
            private byte[] _key;

            public Security() => _key = SHA256.Create().ComputeHash(Encoding.ASCII.GetBytes(_defaultKey));

            public string Encrypt(string data, string key)
            {
                if (!string.IsNullOrEmpty(key))
                {
                    CustomKey(key);
                }

                var encryptor = Aes.Create();

                encryptor.Mode = CipherMode.CBC;

                // Set key and IV
                var aesKey = new byte[32];
                Array.Copy(_key, 0, aesKey, 0, 32);
                encryptor.Key = aesKey;
                encryptor.IV = _iv;

                var memoryStream = new MemoryStream();

                var aesEncryptor = encryptor.CreateEncryptor();

                var cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);

                var plainBytes = Encoding.ASCII.GetBytes(data);

                cryptoStream.Write(plainBytes, 0, plainBytes.Length);

                cryptoStream.FlushFinalBlock();

                var cipherBytes = memoryStream.ToArray();

                memoryStream.Close();
                cryptoStream.Close();

                var cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);

                return cipherText;
            }

            public string Decrypt(string data, string key)
            {
                if (!string.IsNullOrEmpty(key))
                {
                    CustomKey(key);
                }

                var encryptor = Aes.Create();

                encryptor.Mode = CipherMode.CBC;

                var aesKey = new byte[32];
                Array.Copy(_key, 0, aesKey, 0, 32);
                encryptor.Key = aesKey;
                encryptor.IV = _iv;

                var memoryStream = new MemoryStream();

                var aesDecryptor = encryptor.CreateDecryptor();

                var cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);

                var plainText = string.Empty;

                try
                {
                    var cipherBytes = Convert.FromBase64String(data);

                    cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

                    cryptoStream.FlushFinalBlock();

                    var plainBytes = memoryStream.ToArray();

                    plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
                }
                finally
                {
                    memoryStream.Close();
                    cryptoStream.Close();
                }

                return plainText;
            }

            private void CustomKey(string key)
            {
                var blockSize = key.Length / _divisionKey;
                var splitKey = key.CutString(blockSize).ToList();
                var splitDefaultKey = _defaultKey.CutString(blockSize).ToList();
                var newKey = string.Concat(splitDefaultKey.Intertwine(splitKey).ToList());

                _key = SHA256.Create().ComputeHash(Encoding.ASCII.GetBytes(newKey));
            }
        }
    } 

JAVA测试...

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SecurityAESEncryption {


    private static final String _key = "sjkdhfjksdhf3444KDFK4nFLFGKdsnjcnj2cmkeKDIK484dmd999sksksksUUddUZ83k030394m49jdjPuWzRk8Zq2PfnpR3YrYWSq2AaUT6meeC3tr36nTVkuudKWbDyPjhUwbwXBzkUhSPKPpSRheR49em4qJWa6YHSCjKX3K93FEMnqXhYauXwjJwbHXfPWTSdxy6ebCBPyAfqk7Uz5nrRddVjZrxWNCMZYG3PbcvPWA34ekdkd454ldnvJKl";
    private static final char[] initCharArray = new char[]  {0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};
    private static final byte[] initVector =  SecurityAESEncryption.charToByteArray(initCharArray);

    //private static final String initArray = "26dcff00aded7aeec5fe07af4d08223c";
    //private static final byte[] ivValue = SecurityAESEncryption.hexStringToByteArray(initArray);
    //private static final byte[] key = DigestUtils.sha256(_key.getBytes(StandardCharsets.US_ASCII)).;
    private static final byte[] key = SecurityAESEncryption.computeHash(_key);

    public static String encrypt(String value) {
        try {
            System.out.println(key.length);
            System.out.println(Base64.decodeBase64(key).length);
            byte[] aesKey = new byte[32];
            System.arraycopy(key, 0, aesKey, 0, 32);
            SecretKeySpec skeySpec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(initVector);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes());
            return Base64.encodeBase64String(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String encrypted) {
        try {
            byte[] encryptedBytes = Base64.decodeBase64(encrypted);
            System.out.println(key.length);
            System.out.println(Base64.decodeBase64(key).length);
            byte[] aesKey = new byte[32];
            System.arraycopy(key, 0, aesKey, 0, 32);
            IvParameterSpec iv = new IvParameterSpec(initVector);
            SecretKeySpec skeySpec = new SecretKeySpec(aesKey, "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            //byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
            byte[] original = cipher.doFinal(encryptedBytes);

            return new String(original,StandardCharsets.US_ASCII);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

    public static byte[] charToByteArray(char[] x)
    {
        final byte[] res = new byte[x.length];
        for (int i = 0; i < x.length; i++)
        {
            res[i] = (byte) x[i];
        }
        return res;
    }

    public static byte[] computeHash(String input)  {
        try {
        // Static getInstance method is called with hashing SHA
        MessageDigest md = MessageDigest.getInstance("SHA-256");
            return md.digest(input.getBytes(StandardCharsets.US_ASCII));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    public static void main(String[] args) {
        String originalString = "123456!@#";
        System.out.println("Original String to encrypt - " + originalString);
        String encryptedString = encrypt(originalString);

        System.out.println("Encrypted String - " + encryptedString);
        String decryptedString = decrypt("Ci10C7ZjUPoEnitdh7QkEw==");
        System.out.println("After decryption - " + decryptedString);
    }

您编辑的 Java prog 现在成功地将字符串"123456!@#"加密为此(Base64 编码)字符串"LnZV0Vph+eUeJLT2Gst0kw==" ,使用字符串作为 SHA-256 摘要的输入,因此用于 en-/解密是(hex) "07c3491eaa6a6289ca91b7b0f290d60688538860b44753f1cf9617977985d2db"

使用编码字符串作为解密方法的输入会返回原始字符串,但是当使用编码/加密字符串"Ci10C7ZjUPoEnitdh7QkEw=="时,我遇到了这个异常:

javax.crypto.BadPaddingException: Given final block not properly padded.
Such issues can arise if a bad key is used during decryption.

恕我直言,这表明您在 Java 端使用的密钥与在 C# 端使用的密钥不同(我们没有看到 Encrypt 的真正输入,我也不知道“CustomKey”在做什么:-)。

您能否在 encryptor-inits 中设置后直接从 C#-Encrypt 方法中打印出 aeskey 和 -iv 并在此处分享,这可能对我们有用。

public string Encrypt(string data, string key)
...
// Set key and IV
var aesKey = new byte[32];
Array.Copy(_key, 0, aesKey, 0, 32);
encryptor.Key = aesKey;
encryptor.IV = _iv;
==> print aesKey & _iv
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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