【问题标题】:Java Equivalent for .NET Encryption-DESCryptoServiceProvider.NET Encryption-DESCryptoServiceProvider 的 Java 等效项
【发布时间】:2013-06-26 09:38:38
【问题描述】:

Good Day,我需要使用 base64 编码加密一些文本并将编码数据传递给 .NET 应用程序。 .NET 应用程序使用以下编码和解码形式。我试过这个Equivalent to CryptoStream .NET in Java?。 为此,我按照上述链接使用了 Apache commons 编解码器。但是被 cryptoProvider.CreateEncryptor(bytes, bytes) 卡住了,当我检查 java 等效项中的第三个参数时 -

Cipher.init(cipher.ENCRYPT_MODE,key,iv)

它必须是一个 IvParameterSpec。我不知道如何解决这个问题。希望得到一些帮助,干杯!

.NET 加密

static byte[] bytes = ASCIIEncoding.ASCII.GetBytes("mykey");
public static string Encrypt(string originalString)
{        
    DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
    MemoryStream memoryStream = new MemoryStream();
    CryptoStream cryptoStream = new CryptoStream(memoryStream,cryptoProvider.CreateEncryptor(bytes, bytes), CryptoStreamMode.Write);
    StreamWriter writer = new StreamWriter(cryptoStream);
    writer.Write(originalString);
    writer.Flush();
    cryptoStream.FlushFinalBlock();
    writer.Flush();
    return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
}

等价

Java 加密

void encrypt(String inputText) throws Exception {
    try {
        String myKey = "mykey";
        byte[] mybyte = str.getBytes("ASCII");
        //String plainIV = "1234567890ABCDEF";
        KeySpec keySpec = new DESKeySpec(myKey.getBytes("ASCII"));
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
        //IvParameterSpec iv = new IvParameterSpec(org.apache.commons.codec.binary.Hex.decodeHex(plainIV.toCharArray()));
        IvParameterSpec iv = new IvParameterSpec(mybyte);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE,key,iv);
        byte[] encoded = cipher.doFinal(inputText.getBytes("ASCII"));   
        System.out.println("Encoded Value ..... "+Base64.encodeBase64(encoded));
    } catch(UnsupportedEncodingException e) {
        System.out.println("Exception .. "+ e.getMessage());
    }

在 .Net 中,我得到这个 - AOb0B20x2onFGz+JaFBsZyFbvCS9WF49D 作为编码值,但在 java 中,我得到的是有线编码字符串 - =�SKNv?�N�Ɛq{���U�;�/Z��� 8��

编辑:-

跟随zacheusz解决了编码问题,但是.NET和java中的编码字符串不同...

【问题讨论】:

  • 你得到什么错误?您的代码看起来不错(我没有运行它)。能否提供key和IV的真实样本?
  • @zacheusz 我已经用数据更新了我的问题
  • 我想我找到了你的错误。假设您使用的是正确的字符串编码 (ASCII)。我猜它可能是UTF8。看我的回答。

标签: java .net des encryption-symmetric


【解决方案1】:

我看到你在 .NET 中指定 IV:

cryptoProvider.CreateEncryptor(bytes, bytes)

根据documentation,第二个字节数组是IV。所以你应该在 Java 中使用相同的数组。

我认为错误就在这里:

cipher.doFinal(Base64.encodeBase64(inputText.getBytes("ASCII"))); 

在解密之前你是 b64 编码输入。

试试

    byte[] output = cipher.doFinal(inputText.getBytes("ASCII"));  
    System.out.println("Encoded Value ..... "+new String(Base64.encodeBase64(output)));

补充说明(关于您在 cmets 中的问题):

【讨论】:

  • 解决了我的编码问题,但是 .Net 和 Java 中的编码数据是不同的。(当然 iv 在两者中是不同的)。是否可以像在 .NET 中一样使用 byte[] 作为 java 中的 iv?
  • (1.) Java 和 .NET 需要相同的 iv (2.) IvParameterSpec 的构造函数将 byte[] 作为参数 docs.oracle.com/javase/6/docs/api/javax/crypto/spec/… (3.) 在 .NET 中 CreateEncryptor 方法将 byte[] IV 作为第二个参数:msdn.microsoft.com/en-us/library/0dh224hh.aspx
  • 谢谢兄弟!!!,我已将 byte[] 传递给 IvParameterSpec 但存在同样的问题,我已更新我的代码
  • 所以您必须确认几件事:如果您在 .NET (CBC) 中使用相同的模式、相同的填充 (PKCS5Padding) 和相同的字符编码 (ASCII)
  • 从这里 stackoverflow.com/questions/12894722/…>,在 .NET 中,DES 的默认属性是,模式:CBC 和填充:PKCS7,并且字符编码在两者中都是相同的(“ASCII”)。跨度>
【解决方案2】:

谢谢@zacheusz, 我得到了它!!! 这是一个愚蠢的错误,我正在打印 byte[] 值,我忘记将其转换为 String

改变了

System.out.println("编码值....."+Base64.encodeBase64(encoded));

System.out.println("编码值....."+new String(Base64.encodeBase64(encoded),"ASCII");

这解决了我的问题。还用ByteArrayOutputStream 修改了代码。 这是编码和解码功能

String encrypt(String inputText) throws Exception {
    byte[] keyValue = new byte[] { 'm', 'y', 'k', 'e', 'y', 'n', 'u', 'l'};
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    try {           
        KeySpec keySpec = new DESKeySpec(keyValue);
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
        IvParameterSpec iv = new IvParameterSpec(keyValue);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 
        cipher.init(Cipher.ENCRYPT_MODE,key,iv);
        bout.write(cipher.doFinal(inputText.getBytes("ASCII")));                        
    } catch(Exception e) {
        System.out.println("Exception .. "+ e.getMessage());
    }
    return new String(Base64.encodeBase64(bout.toByteArray()),"ASCII");
}

String decrypt(String inputText) throws Exception {
    byte[] keyValue = new byte[] { 'm', 'y', 'k', 'e', 'y', 'n', 'u', 'l'};
    try {
        KeySpec keySpec = new DESKeySpec(keyValue);
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
        IvParameterSpec iv = new IvParameterSpec(keyValue);

        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE,key,iv);
        //byte[] decoded = Base64.decodeBase64(inputText); //Works with apache.commons.codec-1.8
        byte[] decoded = Base64.decodeBase64(inputText.getBytes("ASCII"));// works with apache.commons.codec-1.3
        bout.write(cipher.doFinal(decoded));
    } catch(Exception e) {
        System.out.println("Exception ... "+e);
    }
    return new String(bout.toByteArray(),"ASCII");
}

希望有人会觉得它有帮助...

【讨论】:

    猜你喜欢
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多