当前位置: 首页 > 面试题库 >

Java中的.NET TripleDESCryptoServiceProvider等效项

燕意蕴
2023-03-14
问题内容

拜托,别问我为什么。我只是在.NET中使用此代码来加密/解密数据字符串。我现在需要在Java中使功能完全相同。我已经尝试了多个DESede
crypt的示例,但是没有一个示例与.net中的此类结果相同。

我什至在ssl后面制作了一个.net webserbvice来为.net中编写的这两种方法提供服务,但是这样做太愚蠢了,不能用尽所有的可能性。

也许在该领域中与您关系更密切的一些Java人士将如何制作它。

谢谢 !!!

public class Encryption
{
  private static byte[] sharedkey = {...};
  private static byte[] sharedvector = {...};

  public static String Decrypt(String val)
  {
    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    byte[] toDecrypt = Convert.FromBase64String(val);
    MemoryStream ms = new MemoryStream();
    CryptoStream cs = new CryptoStream(ms, tdes.CreateDecryptor( sharedkey, sharedvector ), CryptoStreamMode.Write);

    cs.Write(toDecrypt, 0, toDecrypt.Length);
    cs.FlushFinalBlock();
    return Encoding.UTF8.GetString(ms.ToArray());
  }

  public static String Encrypt(String val)
  {
    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    byte[] toEncrypt = Encoding.UTF8.GetBytes(val);
    MemoryStream ms = new MemoryStream();
    CryptoStream cs = new CryptoStream(ms, tdes.CreateEncryptor( sharedkey, sharedvector ), CryptoStreamMode.Write);
    cs.Write(toEncrypt, 0, toEncrypt.Length);
    cs.FlushFinalBlock();
    return Convert.ToBase64String(ms.ToArray());
  }
}

Samle输入/输出

String plain = "userNameHere:passwordHere";
Console.WriteLine("plain: " + plain);


String encrypted = Encrypt(plain);
Console.WriteLine("encrypted: " + encrypted);
// "zQPZgQHpjxR+41Bc6+2Bvqo7+pQAxBBVN+0V1tRXcOc="

String decripted = Decrypt(encrypted);
Console.WriteLine("decripted: " + decripted); 
// "userNameHere:passwordHere"

问题答案:

代码如下,但首先要注意一些事项。

  1. 必须为每个消息选择一个不同的初始化向量。硬编码初始化向量没有任何意义。IV应该与密文一起发送给消息接收者(这不是秘密)。
  2. 我将自己的实用程序类用于base-64编码。您可以使用sun.misc.BASE64Encodersun.misc.BASE64Decoder而是使用BouncyCastle之类的第三方库,或者编写自己的库。
  3. 您正在使用2键三重DES,其中第一键和第三键相同。我进行了修改sharedkey以反映这一点,因为Java DESede密码始终需要192位密钥。由密钥生成器来处理密钥选项。
  4. CBC IV只有64位。我只使用的前64位sharedvector

此类应与C#版本互操作。

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Encryption
{

  private static byte[] sharedkey = {
    0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11, 
    0x12, 0x11, 0x0D, 0x0B, 0x07, 0x02, 0x04, 0x08, 
    0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11
  };

  private static byte[] sharedvector = {
    0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11
  };

  public static void main(String... argv)
    throws Exception
  {
    String plaintext = "userNameHere:passwordHere";
    String ciphertext = encrypt(plaintext);
    System.out.println(ciphertext);
    System.out.println(decrypt(ciphertext));
  }

  public static String encrypt(String plaintext)
    throws Exception
  {
    Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sharedkey, "DESede"), new IvParameterSpec(sharedvector));
    byte[] encrypted = c.doFinal(plaintext.getBytes("UTF-8"));
    return Base64.encode(encrypted);
  }

  public static String decrypt(String ciphertext)
    throws Exception
  {
    Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    c.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sharedkey, "DESede"), new IvParameterSpec(sharedvector));
    byte[] decrypted = c.doFinal(Base64.decode(ciphertext));
    return new String(decrypted, "UTF-8");
  }

}

输出:

zQPZgQHpjxR + 41Bc6 + 2Bvqo7 + pQAxBBVN + 0V1tRXcOc =

userNameHere:passwordHere



 类似资料:
  • 问题内容: Printf在1.5版本中添加到Java中,但是我似乎找不到如何将输出发送到字符串而不是文件的方法(这是sprintf在C语言中的作用)。有谁知道如何做到这一点? 问题答案: 查看格式及其语法

  • 问题内容: Java中是否有等效的C#DataTable? 问题答案: 一个类似的问题最近已要求。ResultSet当然不是直接等效的,因为它仅适用于与数据库的活动连接,而DataTable可以“脱机”使用。 从个人经验来看,我会说Java中没有直接等效的功能(尽管还没有尝试过)。您要么使用普通的SQL,要么是您的朋友。或者您使用一些ORM工具,例如Hibernate,Cayenne,Toplin

  • 问题内容: 基于Java的Mahout的 目标是建立可扩展的机器学习库。Python中是否有任何等效的库? 问题答案: 强烈推荐scikits学习http://scikit-learn.sourceforge.net/

  • 问题内容: C#中与DateTime.Ticks等效的Java语言是什么? Java中与上述代码等效的东西是什么? 问题答案: 好吧,java.util.Date / Calendar的精度只有毫秒以下: 那是最接近的有效等效值。如果您需要在.NET ticks值和/ 之间进行转换,则基本上需要执行缩放(刻度到millis)和偏移(从1AD年1月1日到1970年1月1日)。 Java的内置日期和时

  • 问题内容: 我想知道Java中是否有等效于c ++的const。我了解final关键字,但是不幸的是,我不能使用它来声明函数返回值final。相反,它始终确保该功能不能被覆盖,对吗? 基本上,我想确保给定的返回类不能被修改并且是只读的。用Java有可能吗? 问题答案: 基本上,我想确保给定的返回类不能被修改并且是只读的。用Java有可能吗? 一种解决方法不是直接进行,而是一种 不可变的 对象 。

  • 问题内容: 基本上,我希望每10毫秒调用一次函数。 如何在Java中实现? 问题答案: 您可能想看看Timer。