zoukankan      html  css  js  c++  java
  • 使用C# DES解密java DES加密的字符串

    转自 microAllen
     
    最近需要使用C#的DES解密工具类解密字符串,但是要解密的字符串是使用java进行DES加密的,去网上查了关于C#和java关于DES加密解密的资料,发现可以相互加密解密的时候,java进行DES加密一般都会写成如下:
    public static byte[] encrypt(String message, String key) throws Exception {   
      Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");   

      DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));   

      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");   
      // 密钥
      SecretKey secretKey = keyFactory.generateSecret(desKeySpec);   
      // 偏移量
      IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));   
      cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);   

      return cipher.doFinal(message.getBytes("UTF-8"));   
    }

    因为初始化Cipher的时候设置了密钥和偏移量,所以C#的DESCryptoServiceProvider类可以很容易的进行解密。C#解密代码如下:
      public static string Decode(string str, string key)
      {
      try
      {

      DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
      // 密钥
      provider.Key = Encoding.ASCII.GetBytes(key.Substring(0, 8));
      // 偏移量
      provider.IV = Encoding.ASCII.GetBytes(key.Substring(0, 8));
      byte[] buffer = new byte[str.Length / 2];
      for (int i = 0; i < (str.Length / 2); i++)
      {
      int num2 = Convert.ToInt32(str.Substring(i * 2, 2), 0x10);
      buffer[i] = (byte)num2;
      }
      MemoryStream stream = new MemoryStream();
      CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(),CryptoStreamMode.Write);
      stream2.Write(buffer, 0, buffer.Length);
      stream2.FlushFinalBlock();
      stream.Close();
      return Encoding.GetEncoding("GB2312").GetString(stream.ToArray());
      }
      catch (Exception) { return ""; }
      }

    现在的问题是java的DES加密不仅仅有上面一种写法,我需要解密的字符串是使用如下java代码进行加密的:
    public static byte[] encrypt(String message, String key) throws Exception {
      SecureRandom sr = new SecureRandom();
      Cipher cipher = Cipher.getInstance("DES");   

      DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));   

      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");   
      SecretKey secretKey = keyFactory.generateSecret(desKeySpec);   
      // 这里使用的是另一个init方法
      cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);   

      return cipher.doFinal(message.getBytes("UTF-8"));   
    }
    这样的话,java加密的偏移量没有设置,而且通过测试发现就算上面设置了偏移量,Cipher cipher = Cipher.getInstance("DES");和Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 加密之后的结果也不一样,
    所以这样的话使用C#解密的时候就不知道相应的偏移量应该怎么设置,麻烦各位高手指导一下,谢谢

    问题补充:

    DES加密解密结果一般要注意的地方:密钥、偏移量、块密码模式、填充模式
    java DES加密的时候:
    如果使用这种方式,Cipher cipher = Cipher.getInstance("DES"); 此时块密码模式用ECB模式,C#DES类默认模式是CBC模式,所以如果java使用上面的方式进行初始化的时候,使用C#解密的时候要记得设置Mode属性为ECB,另外,如果没有设置偏移量,C#解密的时候Key和IV设置成一样的就可以进行正常解密了。
    所以对于上面java的第2种DES加密方法,使用C#解密的时候只需要在解密之前加上
    provider.Mode = CipherMode.ECB;
    就可以了
  • 相关阅读:
    c++父类指针子类指针转化分析
    setbuf手册
    c++细节
    cf727e
    总结
    UVa 10192 Vacation (最长公共子序列)
    HUNNU 11313 最长公共子序列(LCS)
    HDU 2069 Coin Change (经典DP)
    UVa 674 Coin Change (经典DP)
    UVa 10131 Is Bigger Smarter? (LDS+数据结构排序)
  • 原文地址:https://www.cnblogs.com/pingfan/p/5247570.html
Copyright © 2011-2022 走看看