在C#中用Java解密字符串

时间:2016-05-10 09:06:39

标签: java c# encryption

以下是来自Java的代码:

public static String encrypt(String strToEncrypt)
{
    try
    {
        String secretKey = "1234567890123456";
        DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes("UTF8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey key = keyFactory.generateSecret(keySpec);
        BASE64Encoder base64encoder = new BASE64Encoder();
        byte[] cleartext = strToEncrypt.getBytes("UTF8");
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        String encrypted = base64encoder.encode(cipher.doFinal(cleartext));
        return encrypted;

    }
    catch (Exception e)
    {
        return e.getMessage();
    }
}

如何在C#中解密?尝试了解决方案:

Encrypt in java and Decrypt in C# For AES 256 bit

但它不起作用。

1 个答案:

答案 0 :(得分:2)

基本上,由于您没有向Cipher.Init调用提供初始化向量(IV),因此无法根据您提供的代码可靠地解密该输出。因此,使用随机IV。

以上问题可能在纠正上述问题时起作用。您需要使用正确的IV替换null。

public static string Decrypt(string encrypted)
{
    string secretKey = "1234567890123456";
    byte[] keyBytes = Encoding.UTF8.GetBytes(secretKey);
    byte[] ivBytes = null;

    DESCryptoServiceProvider csp = new DESCryptoServiceProvider();
    ICryptoTransform dec = csp.CreateDecryptor(keyBytes, ivBytes);

    byte[] cipherText = Encoding.UTF8.GetBytes(encrypted);
    string plainText = null;

    using (MemoryStream ms = new MemoryStream(cipherText, false))
    {
        ms.Position = 0;
        using (CryptoStream cryptStrm = new CryptoStream(ms, dec, CryptoStreamMode.Read))
        {
            StreamReader rdr = new StreamReader(cryptStrm);
                plainText = rdr.ReadToEnd();
        }
    }

    return plainText;
}

虽然您正在做的事情存在许多安全问题(同样在我提供的代码中也是如此)。如果这不是一个爱好/理解项目,我建议您重新考虑您的安全设计:

  • 您不应将密钥存储在代码中
  • 您不应将敏感信息存储在字符串对象中
  • 一旦您不再需要0或其他非敏感数据,您应该覆盖敏感信息
  • 您不应该使用DES - 它不再安全
  • 在C#中,您可以使用SecureString来减少敏感信息的泄露(但是,更难以从中获取数据)
  • 理想情况下,加密/解密代码应该以非虚拟化语言完成,因为虚拟机能够在不告诉您的情况下移动数据,因此可能会在内存中留下敏感信息的痕迹
  • ...