C#.NET与JAVA互通之DES加密V2024

net,java,des,v2024 · 浏览次数 : 3

小编点评

本文介绍了如何在C#和Java之间实现DES加密的互通。首先,我们需要了解DES加密算法,并提供了一些工具类来实现C#和Java的DES加密和解密功能。 **一、环境准备** 为了实现C#和Java的互通,我们需要安装相应的开发工具和环境。这里我们使用的是: - .NET Framework 4.6 - JDK 8 (1.8) **二、C# DES加密和解密** C#的DES加密和解密可以通过以下工具类实现: ```csharp using System; using System.Security.Cryptography; using System.Text; namespace CommonUtils { public class DesUtil { // DES加密 public static string DesEncryptCBC(string plainText, string key, string iv) { byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); byte[] keyBytes = Encoding.UTF8.GetBytes(key); byte[] ivBytes = Encoding.UTF8.GetBytes(iv); using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider()) { desAlg.Key = keyBytes; desAlg.IV = ivBytes; desAlg.Mode = CipherMode.CBC; desAlg.Padding = PaddingMode.PKCS7; using (ICryptoTransform encryptor = desAlg.CreateEncryptor()) { byte[] encrypted = encryptor.TransformFinalBlock(plainTextBytes, 0, plainTextBytes.Length); return Convert.ToBase64String(encrypted); } } } // DES解密 public static string DesDecryptCBC(string cipherText, string key, string iv) { byte[] cipherTextBytes = Base64.GetDecoder().Decode(cipherText); byte[] keyBytes = Encoding.UTF8.GetBytes(key); byte[] ivBytes = Encoding.UTF8.GetBytes(iv); using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider()) { desAlg.Key = keyBytes; desAlg.IV = ivBytes; desAlg.Mode = CipherMode.CBC; desAlg.Padding = PaddingMode.PKCS7; using (ICryptoTransform decryptor = desAlg.CreateDecryptor()) { byte[] decrypted = decryptor.TransformFinalBlock(cipherTextBytes, 0, cipherTextBytes.Length); return Encoding.UTF8.GetString(decrypted); } } } } } ``` **三、Java DES加密和解密** Java的DES加密和解密可以通过以下工具类实现: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class DesUtil { private static final String charset = "UTF-8"; public static String DesEncryptCBC(String content, String key, String iv) throws Exception { // 明文 byte[] contentBytes = content.getBytes(charset); // DES KEY byte[] keyBytes = key.getBytes(charset); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "DES"); // DES IV byte[] initParam = iv.getBytes(charset); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec); byte[] byEnd = cipher.doFinal(contentBytes); // 加密后的byte数组转BASE64字符串 String strEnd = Base64.getEncoder().encodeToString(byEnd); return strEnd; } // 解密 public static String DesDecryptCBC(String content, String key, String iv) throws Exception { // 反向解析BASE64字符串为byte数组 byte[] encryptedBytes = Base64.getDecoder().decode(content); // DES KEY byte[] keyBytes = key.getBytes(charset); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "DES"); // DES IV byte[] initParam = iv.getBytes(charset); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec); byte[] byEnd = cipher.doFinal(encryptedBytes); // 加密后的byte数组直接转字符串 String strEnd = new String(byEnd, charset); return strEnd; } } ``` **四、注意事项** 1. 字符串转byte数组时,双方要约定好编码,一般使用UTF8。 2. 加密和解密过程中,明文和密文都需要使用相同的编码。 3. 注意C#中的PKCS7Padding对应Java中的PKCS5Padding。 4. 在解密时,解密出的明文结果也需要使用UTF8编码转换。 通过以上步骤,我们可以实现在C#和Java之间的DES加密互通。

正文

C#.NET与JAVA互通之DES加密V2024
 
配置视频:
 
 
环境:
.NET Framework 4.6 控制台程序
JAVA这边:JDK8 (1.8) 控制台程序
 

注意点:

1.由于密钥、明文、密文的输入输出参数,都是byte数组(byte[]),所以:字符串转byte数组(byte[])环节,双方要约定好编码。

2. KEY 和 IV 从字符串转byte数组(byte[])时,双方要约定好编码,一般是UTF8。

3.明文从字符串转byte数组(byte[])时,双方要约定好编码,一般是UTF8,.NET 这边要注意:不能用 Encoding.Default。

4.加密后的结果,从byte数组(byte[])转字符串时,双方要约定好编码,一般是Base64字符串。

5.NET 的PKCS7Padding 对应 JAVA 的:PKCS5Padding

一、 .NET DES

先看工具类:DesUtil

using System;
using System.Security.Cryptography;
using System.Text;

namespace CommonUtils
{
    /// <summary>
    /// 工具类,2024-06-16,runliuv。
    /// </summary>
    public class DesUtil
    {
        public static byte[] DesEncryptCBC(byte[] plainText, byte[] Key, byte[] IV)
        {
            byte[] encrypted;

            using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
            {
                desAlg.Key = Key;
                desAlg.IV = IV;
                desAlg.Mode = CipherMode.CBC;
                desAlg.Padding = PaddingMode.PKCS7;

                using (ICryptoTransform encryptor = desAlg.CreateEncryptor())
                {
                    encrypted= encryptor.TransformFinalBlock(plainText, 0, plainText.Length);
                }
            }

            return encrypted;
        }

        public static byte[] DesDecryptCBC(byte[] cipherText, byte[] Key, byte[] IV) 
        {
            byte[] plaintext = null;

            using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
            {
                desAlg.Key = Key;
                desAlg.IV = IV;
                desAlg.Mode = CipherMode.CBC;
                desAlg.Padding = PaddingMode.PKCS7;

                using (ICryptoTransform decryptor = desAlg.CreateDecryptor()) 
                { 
                    plaintext = decryptor.TransformFinalBlock(cipherText, 0, cipherText.Length);
                }
            }

            return plaintext;
        }
        /// <summary>
        /// DES CBC 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="Key">密钥</param>
        /// <param name="IV"></param>
        /// <returns></returns>
        public static string DesEncryptCBC(string plainText, string Key, string IV)
        {
            byte[] yy= DesEncryptCBC(Encoding.UTF8.GetBytes(plainText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
            string xx=Convert.ToBase64String(yy);
            return xx;
        }
        /// <summary>
        /// DES CBC 解密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="Key">密钥</param>
        /// <param name="IV"></param>
        /// <returns></returns>
        public static string DesDecryptCBC(string cipherText, string Key, string IV)
        {
            byte[] yy = DesDecryptCBC(Convert.FromBase64String(cipherText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
            string xx = Encoding.UTF8.GetString(yy);
            return xx;
        }
    }
}

.NET 使用这个工具类,做DES CBC 加密 :

static void TestDesCbc()
{
    Console.WriteLine("-- Test Cbc --");
    string aesKey = "12345678";// DES 密钥长度是8位
    string aesIV = "abcdefgh";// DES IV长度是8位

    string orgStr = "hello .net 2024-06-10";
    string encryptedStr = DesUtil.DesEncryptCBC(orgStr, aesKey, aesIV);
    Console.WriteLine("加密字符串:" + encryptedStr);

    //自加,自解
    string decryptedStr = DesUtil.DesDecryptCBC(encryptedStr, aesKey, aesIV);
    Console.WriteLine("自加,自解:" + decryptedStr);
}

.NET 输出结果 :

-- Test Cbc --
加密字符串:yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A
自加,自解:hello .net 2024-06-10
结束 。

.NET 简要说明:

加密:

 

public static string DesEncryptCBC(string plainText, string Key, string IV)
{
    byte[] yy= DesEncryptCBC(Encoding.UTF8.GetBytes(plainText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
    string xx=Convert.ToBase64String(yy);
    return xx;
}

 

Encoding.UTF8.GetBytes(plainText),明文字符串转byte数组 使用UTF8。

Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV),KEY 和 IV 转byte数组 使用UTF8。

public static byte[] DesEncryptCBC(byte[] plainText, byte[] Key, byte[] IV)
{
    byte[] encrypted;

    using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
    {
        desAlg.Key = Key;
        desAlg.IV = IV;
        desAlg.Mode = CipherMode.CBC;
        desAlg.Padding = PaddingMode.PKCS7;

        using (ICryptoTransform encryptor = desAlg.CreateEncryptor())
        {
            encrypted= encryptor.TransformFinalBlock(plainText, 0, plainText.Length);
        }
    }

    return encrypted;
}

创建一个DESCryptoServiceProvider对象,指定KEY 和 IV,指定 加密模式和 PADDING。

创建加密器对象:desAlg.CreateEncryptor()。

使用 TransformFinalBlock 算出加密结果。

string xx=Convert.ToBase64String(yy); 加密后的结果转字符串时,使用Base64字符串。

 

解密:

public static string DesDecryptCBC(string cipherText, string Key, string IV)
{
    byte[] yy = DesDecryptCBC(Convert.FromBase64String(cipherText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
    string xx = Encoding.UTF8.GetString(yy);
    return xx;
}

 

 

Convert.FromBase64String(cipherText),由于加密结果集转字符串时用的base64,所以密文转byte数组时,就要用Convert.FromBase64String。

 

KEY 和 IV 就不用多说了。

public static byte[] DesDecryptCBC(byte[] cipherText, byte[] Key, byte[] IV) 
{
    byte[] plaintext = null;

    using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
    {
        desAlg.Key = Key;
        desAlg.IV = IV;
        desAlg.Mode = CipherMode.CBC;
        desAlg.Padding = PaddingMode.PKCS7;

        using (ICryptoTransform decryptor = desAlg.CreateDecryptor()) 
        { 
            plaintext = decryptor.TransformFinalBlock(cipherText, 0, cipherText.Length);
        }
    }

    return plaintext;
}

 

创建一个DESCryptoServiceProvider对象,指定KEY 和 IV,指定 模式和 PADDING。

创建解密器对象:desAlg.CreateDecryptor()。

使用 TransformFinalBlock 解密出结果。

string xx = Encoding.UTF8.GetString(yy);  加密时,明文转byte[] 时用的UTF8,那解密出的明文结果,转byte数组时,也得用UTF8。

 

可以说,解密与加密是相反的。 

 

 

二、JAVA DES

还是简要封装个工具类DesUtil。

package org.runliuv;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class DesUtil {

    private static final String charset = "UTF-8";

    public static String DesEncryptCBC(String content, String key, String iv)
            throws Exception {

        //明文
        byte[] contentBytes = content.getBytes(charset);

        //DES KEY
        byte[] keyBytes = key.getBytes(charset);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "DES");

        //DES IV
        byte[] initParam = iv.getBytes(charset);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
        byte[] byEnd = cipher.doFinal(contentBytes);

        //加密后的byte数组转BASE64字符串
        String strEnd = Base64.getEncoder().encodeToString(byEnd);
        return strEnd;
    }

    /**
     * 解密
     * @param content
     * @param key
     * @param iv
     * @return
     * @throws Exception
     */
    public static String DesDecryptCBC(String content, String key, String iv)
            throws Exception {
        //反向解析BASE64字符串为byte数组
        byte[] encryptedBytes = Base64.getDecoder().decode(content);

        //DES KEY
        byte[] keyBytes = key.getBytes(charset);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "DES");

        //DES IV
        byte[] initParam = iv.getBytes(charset);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
        byte[] byEnd = cipher.doFinal(encryptedBytes);

        //加密后的byte数组直接转字符串
        String strEnd = new String(byEnd, charset);
        return strEnd;
    }


}

JAVA 使用工具类进行 DES CBC 加密,解密:

System.out.println("-- Test Cbc --");
            String aesKey = "12345678";// DES 密钥长度是8位
            String aesIV = "abcdefgh";// DES IV长度是8位

            String orgStr = "hello JAVA 2024-06-10";
            System.out.println("待加密字符串:" + orgStr);
            String encryptedStr = DesUtil.DesEncryptCBC(orgStr, aesKey, aesIV);
            System.out.println("加密后:" + encryptedStr);

            //自加,自解
            String decryptedStr = DesUtil.DesDecryptCBC(encryptedStr, aesKey, aesIV);
            System.out.println("自加,自解:" + decryptedStr);

 

效果:

-- Test Cbc --
待加密字符串:hello JAVA 2024-06-10
加密后:VkxvjXu1YKvQJF8MPnFvXhFzJgZI4j9I
自加,自解:hello JAVA 2024-06-10

 

 

三、.NET 加 JAVA 解

先用.NET 对"hello .net 2024-06-10",这个字符串加密,KEY是"12345678",IV为“abcdefgh”,加密结果为:

yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A

 

将这个串复制到JAVA代码,进行解密:

String NETStr ="yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A";
            System.out.println(".NET 加密后的串:" + NETStr);
            String decryptedStr = DesUtil.DesDecryptCBC(NETStr, aesKey, aesIV);
            System.out.println("JAVA解密:" + decryptedStr);

输出结果 :

-- Test Cbc --
.NET 加密后的串:yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A
JAVA解密:hello .net 2024-06-10

 

--

DES ECB 的加密模式,请自行探索。

与C#.NET与JAVA互通之DES加密V2024相似的内容:

C#.NET与JAVA互通之DES加密V2024

C#.NET与JAVA互通之DES加密V2024 配置视频: 环境: .NET Framework 4.6 控制台程序 JAVA这边:JDK8 (1.8) 控制台程序 注意点: 1.由于密钥、明文、密文的输入输出参数,都是byte数组(byte[]),所以:字符串转byte数组(byte[])环节,

C#.NET与JAVA互通之MD5哈希V2024

C#.NET与JAVA互通之MD5哈希V2024 配套视频: 要点: 1.计算MD5时,SDK自带的计算哈希(ComputeHash)方法,输入输出参数都是byte数组。就涉及到字符串转byte数组转换时,编码选择的问题。 2.输入参数,字符串转byte数组时,编码双方要统一,一般为:UTF-8。

C#.NET与JAVA互通之AES加密解密V2024

C#.NET与JAVA互通之AES加密解密V2024 视频: 注意点: 1. KEY 和 IV 从字符串转byte数组时,双方要约定好编码,一般是UTF8。 2.明文从字符串转byte数组时,双方要约定好编码,一般是UTF8,也可以GB2312,但不能Encoding.Default。 3.加密后的

.NET科普:.NET简史、.NET Standard以及C#和.NET Framework之间的关系

最近在不少自媒体上看到有关.NET与C#的资讯与评价,感觉大家对.NET与C#还是不太了解,尤其是对2016年6月发布的跨平台.NET Core 1.0,更是知之甚少。在考虑一番之后,还是决定写点东西总结一下,也回顾一下.NET的发展历史。 首先,你没看错,.NET是跨平台的,可以在Windows、

C#.Net筑基-基础知识

C# (读作C Sharp)是由微软公司开发的一种面向对象、类型安全、高效且简单的编程语言,最初于 2000 年发布,并随后成为 .NET 框架的一部分。所以学习C#语言的同时,也是需要同步学习.NET框架的,不过要要注意C#与.NET的对应版本。

Unity框架与.NET, Mono框架的关系

什么是C# C#是一种面向对象的编程语言。 什么是.NET .NET是一个开发框架,它遵循并采用CIL(Common Intermediate Language)和CLR(Common Language Runtime)两种约定, CIL标准为一种编译标准:将不同编程语言(C#, JS, VB等)使

像go 一样 打造.NET 单文件应用程序的编译器项目bflat 发布 7.0版本

现代.NET和C#在低级/系统程序以及与C/C++/Rust等互操作方面的能力完全令各位刮目相看了,有人用C#开发的64位操作系统: GitHub - nifanfa/MOOS: C# x64 operating system pro...,截图要介绍的是一个结合Roslyn和NativeAOT的实

.NET周报 【5月第4期 2023-05-27】

## 国内文章 ### C#使用词嵌入向量与向量数据库为大语言模型(LLM)赋能长期记忆实现私域问答机器人落地之openai接口平替 https://www.cnblogs.com/gmmy/p/17430613.html 在上一篇[文章](https://www.cnblogs.com/gmmy/

[转帖]别催了,别催了,这篇文章我一次性把 Shell 的内容说完

https://my.oschina.net/jiagoushi/blog/6037198 Shell 搜索与匹配 1、在文件中查找字符串 grep 命令可以搜索文件,查找指定的字符串。 $ grep myvar *.c 在这个例子中,我们搜索的文件全都位于当前目录下。因此,我们只使用了简单的 sh

如何洞察 .NET程序 非托管句柄泄露

## 一:背景 ### 1. 讲故事 很多朋友可能会有疑问,C# 是一门托管语言,怎么可能会有非托管句柄泄露呢? 其实一旦 C# 程序与 C++ 语言交互之后,往往就会被后者拖入非托管泥潭,让我们这些调试者被迫探究 `非托管领域问题`。 ## 二:非托管句柄泄露 ### 1. 测试案例 为了方便讲述