首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# DES与Java DES Byte[]和BlockSize不同

C# DES与Java DES Byte[]和BlockSize不同
EN

Stack Overflow用户
提问于 2019-06-28 14:21:50
回答 1查看 303关注 0票数 1

我很难让Java代码输出与C#代码相同的C#。

C#代码:

代码语言:javascript
复制
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class Program
{
    private const string k = "A2B3C4D1";
    private const string kiv = "1A2B3C4D";
    
    public static void Main()
    {
        encrypt("peanuts");
    }
    
    public static void encrypt(string str)
    {
        try
        {
            using (var ms = new MemoryStream())
            using (var csp = new DESCryptoServiceProvider() { Key = Encoding.UTF8.GetBytes(k), IV =  Encoding.UTF8.GetBytes(kiv) })
            {
                Console.WriteLine("Algorithm: DES?/" + csp.Mode + "/" + csp.Padding);
                Console.WriteLine("BlockSize: " + csp.BlockSize);

                using (var cs = new CryptoStream(ms, csp.CreateEncryptor(), CryptoStreamMode.Write))
                using (var sw = new StreamWriter(cs))
                    sw.WriteLine(str);

                byte[] barray = ms.ToArray();

                Console.WriteLine("barray length: " + barray.Length);
            
                Console.WriteLine("barray: " + string.Join(" ", barray));
            }
        }
        catch (Exception ex) { Console.Write(ex.ToString()); }
    }
}

Java代码:

代码语言:javascript
复制
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.security.Security;

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

public class MyClass {
    private static final String k = "A2B3C4D1";
    private static final String kiv = "1A2B3C4D";
    
    public static void main(String args[]) {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        encrypt("peanuts");
    }
    
    public static void encrypt(String str) {
        try {
            SecretKeySpec key = new SecretKeySpec(k.getBytes(Charset.forName("UTF-8")), "DES");
            IvParameterSpec iv = new IvParameterSpec(kiv.getBytes(Charset.forName("UTF-8")));
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS7Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key, iv);
            
            System.out.println("Algorithm: " + cipher.getAlgorithm());
            System.out.println("BlockSize: " + cipher.getBlockSize());
    
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            CipherOutputStream cos = new CipherOutputStream(out, cipher);
            
            cos.write(str.getBytes());
            cos.close();
            
            byte[] barray = out.toByteArray();
            
            System.out.println("barray length: " + barray.length);
        
            System.out.print("barray: ");
            for(byte b : barray){
                System.out.print(" " + b);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

C#输出

算法:DES/CBC/PKCS7 7 BlockSize: 64 barray长度: 16 酒吧: 107 125 91 205 77 206 98 120 214 194 64 167 128 97 132 75 base64: a31bzU3OYnjWwkCngGGESw==

Java输出

算法: DES/CBC/PKCS7Padding 7填充 BlockSize: 8 巴尔长度:8 酒吧: 45 100 -86 103 9 -7 -19 -76 base64: LWSqZwn57bQ=

我正试图从Byte[]代码中获得与C#完全相同的C#输出。但我所看到的唯一不同之处是,块大小与两者不同。

C# Dot.Net Fiddle

Java jDoodle.com

我只是不明白,有什么是我遗漏的还是不明白的?

编辑

我添加了代码来打印字符串中的字节数组,它不同:

C#

代码语言:javascript
复制
barray length: 16
barray: 107 125 91 205 77 206 98 120 214 194 64 167 128 97 132 75
base64: a31bzU3OYnjWwkCngGGESw==

Java

代码语言:javascript
复制
barray length: 8
barray: 45 100 -86 103 9 -7 -19 -76
base64: LWSqZwn57bQ=
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-28 15:44:50

@JamesKPolk是正确的:您正在用C#加密C#,用Java加密{ (byte)'p', (byte)'e', (byte)'a', (byte)'n', (byte)'u', (byte)'t', (byte)'s' }

因为“花生”是(在UTF-8中)7个字节,所以它可以被PKCS7填充到一个DES块中。接下来的1-8字节会导致第二个块.你又加了两个。

将Dot.Net填充中的代码更改为Write而不是WriteLine生成

代码语言:javascript
复制
Algorithm: DES?/CBC/PKCS7
BlockSize: 64
barray length: 8
barray: 45 100 170 103 9 249 237 180
barray: LWSqZwn57bQ=

现在唯一的区别是,C# BlockSize是位的,而您的BlockSize代码将它作为字节。

在您的"peanuts"中将"peanuts\r\n"更改为JDoodle,您将得到

代码语言:javascript
复制
Algorithm: DES/CBC/PKCS7Padding
BlockSize: 8
barray length: 16
barray:  107 125 91 -51 77 -50 98 120 -42 -62 64 -89 -128 97 -124 75
barray: a31bzU3OYnjWwkCngGGESw==

这是相同的,如果barray十进制内容被打印为无符号值而不是有符号值(将256个添加到所有负数中) --这个事实在Base64中是相同的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56808655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档