首页 > 编程语言 >C#.NET与JAVA互通之DES加密V2024

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

时间:2024-06-16 17:44:05浏览次数:14  
标签:加密 string V2024 C# DES IV desAlg byte

C#.NET与JAVA互通之DES加密V2024   配置视频: <iframe frameborder="no" height="600" scrolling="no" src="//player.bilibili.com/player.html?isOutside=true&aid=112625534897355&bvid=BV1gJVLepEGS&cid=500001584118309&p=1" width="800"></iframe>     环境: .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 的加密模式,请自行探索。

标签:加密,string,V2024,C#,DES,IV,desAlg,byte
From: https://www.cnblogs.com/runliuv/p/18250252

相关文章

  • 【CICID】GitHub-Actions语法
    目录【CICID】GitHub-Actions语法1场景2CI/CD2.1什么是CI/CD2.2持续集成(CI)2.3持续部署(CD)3介绍3.1优点4工作流常用语法4.1name:工作流名称4.2on:触发工作流时机4.3jobs:作业5环境变量5.1自定义变量5.1.1在env中定义变量5.1.2Run通过写入到github变量5.2......
  • (pdf)数据结构与算法分析 Java语言描述=Data Structures and Algorithm Analysis in Jav
    书:pan.baidu.com/s/1tGbGhhQ3Ez1SIkqdEREsjQ?pwd=eqp0提取码:eqp0数组:作为最基本的数据结构,用于存储固定大小的同类型元素集合。链表:动态数据结构,允许在任意位置插入和删除元素。栈:后进先出(LIFO)的数据结构,常用于函数调用和表达式求值。队列:先进先出(FIFO)的数据结构,常用于任务调......
  • CMU最新论文:机器人智慧流畅的躲避障碍物论文详细讲解
    CMU华人博士生TairanHe最新论文:AgileButSafe:LearningCollision-FreeHigh-SpeedLeggedLocomotion代码开源:Code:https://github.com/LeCAR-Lab/ABSB站实际效果展示视频地址:bilibili效果地址我会详细解读论文的内容,让我们开始吧。敏捷且安全:学习无碰撞的高速腿......
  • 【iOS】自定义cell及其复用机制
    文章目录cell的复用注册非注册两者的区别自定义cellcell的复用当用户滚动UITableView或UICollectionView时,只有少量可见的cell会被实际创建和显示。对于那些暂时不可见的cell,系统会将它们缓存起来以备将来复用。这就是所谓的cell复用机制。为什么需要......
  • scikit-learn (sklearn) 基础教程
    scikit-learn(sklearn)基础教程scikit-learn是一个强大的Python库,用于机器学习和数据挖掘。它基于SciPy、NumPy和matplotlib构建,提供了简单且高效的工具,适用于数据分析和建模。目录安装数据集加载数据预处理模型训练与预测模型评估超参数调优示例:鸢尾花分类安......
  • GitHub Copilot 登录账号激活,已经在IntellJ IDEA使用
    GitHubCopilot想必大家都是熟悉的,一款AI代码辅助神器,相信对编程界的诸位并不陌生。今日特此分享一项便捷的工具,助您轻松激活GitHubCopilot,尽享智能编码之便利!GitHubCopilot是由GitHub和OpenAI共同开发的人工智能代码辅助工具,所以该插件是专门提供给程序员来写代......
  • GitHub Copilot 登录账号激活,在pycharm写代码的效率提高了
    GitHubCopilot想必大家都是熟悉的,一款AI代码辅助神器,相信对编程界的诸位并不陌生。今日特此分享一项便捷的工具,助您轻松激活GitHubCopilot,尽享智能编码之便利!GitHubCopilot是由GitHub和OpenAI共同开发的人工智能代码辅助工具,所以该插件是专门提供给程序员来写代......
  • 最实用的 LeetCode 刷题指南
    暑期实习基本结束了,校招即将开启。当前就业环境已不再是那个双向奔赴时代了。求职者在变多,岗位在变少,要求还更高了,最近社群又开始活跃起来了,各种讨论、各种卷。为方便大家快手入手、节省时间,我整理了一份算法指南:汇总合集:内容不仅仅是大模型,也包括LeetCode刷题技巧《......
  • JavaWeb学习-MVC
    前言基于JavaWeb基础知识进行优化,形成了MVC的开发模式。程序结构优化教程原来案例中的servlet太多了,希望只有一个servlet,把原来多个servlet的合并成一个,根据参数operation判断用哪个方法并用反射调用,都写到了新servlet的service方法中了。引入dispatcherservlet,作为中心控制器,......
  • JavaWeb学习-tomcat和servlet
    前言本文介绍javaweb的基本知识,包括CS和BS的架构形式、web容器、servlet等。CS和BSCS:客户端服务器架构模式优点:充分利用客户端机器的资源,减轻服务器的负荷。缺点:需要安装;升级维护成本较高。BS:浏览器服务器架构模式优点:客户端不需要安装;维护成本较低。缺点:所有的计算和存储......