【问题标题】:3DES Decrypt in java a token encrypted in C#3DES在java中解密一个用C#加密的令牌
【发布时间】:2013-11-21 12:30:50
【问题描述】:

在问之前我已经搜索了很多,但是我发现的想法都没有解决我的问题,所以这是我的问题:

  1. 在 C# 中,用于加密的代码(我无法更改,因为它来自另一个应用程序)在后面详细说明。
  2. 我必须在 Java 中解密加密的令牌,但到目前为止没有任何效果,有人可以帮忙吗?

对于1.C#代码:

    static public string Encrypt3DES(string toEncrypt, string SecKey, string IV){
    byte[] keyArray;
    try
    {
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

    MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
        keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(SecKey));
        hashmd5.Clear();      

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();

        tdes.Key = keyArray;      
        tdes.Mode = CipherMode.CBC;
    tdes.Padding = PaddingMode.PKCS7;
        tdes.IV = UTF8Encoding.UTF8.GetBytes(IV);

        ICryptoTransform cTransform = tdes.CreateEncryptor();

        //transform the specified region of bytes array to resultArray
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
    tdes.Clear();

    //Return the encrypted data into unreadable string format
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }
    catch (Exception e) { return string.Empty; }
    }

对于 2 个不起作用的 Java 代码:

    public class TripleDesTest {

private KeySpec keySpec;
private SecretKey key;
private IvParameterSpec iv;

public TripleDesTest() {
    String keyString = "THE_KEY";
    String ivString = "THE_IV";

    try {
        final MessageDigest md = MessageDigest.getInstance("md5");
        final byte[] digestOfPassword = md.digest(Base64.decodeBase64(keyString.getBytes("UTF-8")));            
        final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
        for (int j = 0, k = 16; j < 8;) {
            keyBytes[k++] = keyBytes[j++];
        }

        keySpec = new DESedeKeySpec(keyBytes);

        key = SecretKeyFactory.getInstance("DESede").generateSecret(keySpec);

        iv = new IvParameterSpec(ivString.getBytes("UTF-8"));
    } catch (Exception e) {
        e.printStackTrace();
    }

}


public String decrypt(String value) {

    try {
        Cipher dcipher = Cipher.getInstance("DESede/CBC/PKCS5Padding", "SunJCE");
        dcipher.init(Cipher.DECRYPT_MODE, key, iv);

        if (value == null)
            return null;

        // Decode base64 to get bytes
        byte[] dec = Base64.decodeBase64(value.getBytes("UTF-8"));

        // Decrypt
        byte[] utf8 = dcipher.doFinal(dec);

        // Decode using UTF-8
        return new String(utf8, "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;

}
    }

【问题讨论】:

  • Java/C# 中有不同的填充模式。你确定应该这样吗?
  • 我了解到 PKCS7 和 PKCS5 是兼容的(经过一些谷歌搜索),并且 PKCS7 在 Java 标准中不存在。我也尝试查看 Base64 编码/解码的差异,但没有成功......

标签: c# java encryption base64 3des


【解决方案1】:

这是问题的解决方案(我终于能够自己解决这个问题):

在Java中,替换

final byte[] digestOfPassword = md.digest(Base64.decodeBase64(keyString.getBytes("UTF-8")));`

与:

final byte[] digestOfPassword = md.digest(keyString.getBytes("UTF-8"));

因为在 C# 端,没有使用 Base64 作为密钥:

keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(SecKey));

【讨论】:

    猜你喜欢
    • 2012-11-20
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多