Java和C#中3DES的加密与解密
发布日期:2021-07-13 02:57:12 浏览次数:2 分类:技术文章

本文共 6515 字,大约阅读时间需要 21 分钟。

最近在工作中遇到将Java环境的一个用户ID用表单形式传递给.net环境做校验,考虑到不能将用户ID作为明文传递,因此利用简单的3DES进行加密解密操作。

需要注意的就是:

(1)两种环境下3DES加密解密的一致性问题:C#会对解密生成的byte在不满足长度16时,自动填充'/0'直至长度为16,因此在接收到Java端的加密数据后,我们要对生成的byte做处理把末尾的'\0'去掉。

(2)另外在传输上我们采用BASE64编码传输,一方面它具有简单的不可读性,另一方面它能规避一些特殊字符的传输问题。

下面的Java中3DES加密解密的示例代码:

import java.security.Key;import java.io.IOException;import java.security.InvalidKeyException;import javax.crypto.Cipher;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESedeKeySpec;import javax.crypto.spec.IvParameterSpec;import java.util.Scanner;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class destest {			public static void main(String[] args) throws Exception {		// TODO Auto-generated method stub		byte[] key = new BASE64Decoder().decodeBuffer("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");		byte[] keyiv = {1, 2, 3, 4, 5, 6, 7, 8};		Scanner sc = new Scanner(System.in);		System.out.println("请输入加密前的字符串:");		String str = sc.nextLine();		System.out.println("原始字符串为: " + str);				byte[] data = str.getBytes("UTF-8");				System.out.println("开始CBC加密解密");				byte[] strEncode = des3EncodeCBC(key, keyiv, data);		System.out.println("以BASE64编码输出加密后的byte为:" + new BASE64Encoder().encode(strEncode));  		for (int i = 0; i < strEncode.length; i++)                  // 输出加密后的strEncode每字节的内容		{			System.out.println("Encode byte[" + i + "]  " + strEncode[i]);		}				byte[] strDecode = des3DecodeCBC(key, keyiv, strEncode);		String strGet = new String(strDecode, "UTF-8");		System.out.println("解密后的字符串内容为:" + strGet);		for (int i = 0; i < strDecode.length; i++)                  // 输出解密后strDecode每字节的内容		{			System.out.println("Decode byte[" + i + "]  " + strDecode[i]);		}					}		public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception	{		Key deskey = null;		DESedeKeySpec spec = new DESedeKeySpec(key);		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");		deskey = keyfactory.generateSecret(spec);		Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");		IvParameterSpec ips = new IvParameterSpec(keyiv);		cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);		byte[] bOut = cipher.doFinal(data);		return bOut;	}		public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception	{		Key deskey = null;		DESedeKeySpec spec = new DESedeKeySpec(key);		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");		deskey = keyfactory.generateSecret(spec);		Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");		IvParameterSpec ips = new IvParameterSpec(keyiv);		cipher.init(Cipher.DECRYPT_MODE, deskey, ips);		byte[] bOut = cipher.doFinal(data);		return bOut;	}}
运行例子如下图所示:

下面是C#中3DES加密解密的示例代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Security.Cryptography;namespace DES{    class Program    {        private static byte[] key = Convert.FromBase64String("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");        private static byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };        public static byte[] Des3EncodeCBC(byte[] key, byte[] iv, byte[] data)        {            try            {                MemoryStream mStream = new MemoryStream();                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();                tdsp.Mode = CipherMode.CBC;                tdsp.Padding = PaddingMode.PKCS7;                CryptoStream cStream = new CryptoStream(mStream, tdsp.CreateEncryptor(key, iv), CryptoStreamMode.Write);                cStream.Write(data, 0, data.Length);                cStream.FlushFinalBlock();                byte[] ret = mStream.ToArray();                cStream.Close();                mStream.Close();                return ret;            }            catch (CryptographicException e)            {                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);                return null;            }        }        public static byte[] Des3DecodeCBC(byte[] key, byte[] iv, byte[] data)        {            try            {                MemoryStream msDecrypt = new MemoryStream(data);                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();                tdsp.Mode = CipherMode.CBC;                tdsp.Padding = PaddingMode.PKCS7;                CryptoStream csDecrypt = new CryptoStream(msDecrypt, tdsp.CreateDecryptor(key, iv), CryptoStreamMode.Read);                byte[] fromEncrypt = new byte[data.Length];                csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);                return fromEncrypt;            }            catch(CryptographicException e)            {                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);                return null;            }        }         static void Main(string[] args)        {            System.Text.Encoding utf8 = System.Text.Encoding.UTF8;            Console.WriteLine("请输入加密前的字符串:");            string str = Console.ReadLine();            Console.WriteLine("原始字符串为: " + str);            byte[] data = utf8.GetBytes(str);            System.Console.WriteLine("开始CBC加密解密");            byte[] strEncode = Program.Des3EncodeCBC(key, iv, data);            string base64Str = Convert.ToBase64String(strEncode);            System.Console.WriteLine("以BASE64编码输出加密后的byte为:" + base64Str);            for (int i = 0; i < strEncode.Length; i++)          // 输出加密后的strEncode每字节的内容            {                Console.WriteLine("Encode : byte[" + i + "]  " + strEncode[i]);            }            byte[] strDecode = Program.Des3DecodeCBC(key, iv, strEncode);            string strGet = utf8.GetString(strDecode);            Console.WriteLine("解密后的字符串内容为:" + strGet + ",长度为" + strGet.Length);            for (int i = 0; i < strDecode.Length; i++)          // 输出加密后的strDecode每字节的内容            {                Console.WriteLine("Decode byte[" + i + "]  " + strDecode[i]);            }            // 去除生成byte的末尾的一些ASCII码为0的字符            int len = 0;            for (int i = 0; i < strDecode.Length; i++)            {                if (strDecode[i] != 0)                    len++;            }            byte[] strDecodeEmit = new byte[len];            for (int i = 0; i < len; i++)            {                strDecodeEmit[i] = strDecode[i];            }            System.Console.WriteLine("去掉末尾0后获得的字符串为:" + utf8.GetString(strDecodeEmit) + ",长度为:" + utf8.GetString(strDecodeEmit).Length);            System.Console.ReadLine();        }    }}

运行例子如下图所示:

转载地址:https://blog.csdn.net/buaa_shang/article/details/50246337 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JUnit简单教程
下一篇:Java面向对象知识点总结

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年02月28日 06时43分33秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

php apc.dll下载,PHP之APC缓存详细介绍 apc模块安装 2019-04-21
html贝塞尔曲线在线,贝塞尔曲线的一些事情_html/css_WEB-ITnose 2019-04-21
Java前台显示近20天的东西_第十次课:前台首页设计及显示商品信息 2019-04-21
java开发web网站的路由设计_理解Web路由(浅谈前后端路由与前后端渲染) 2019-04-21
excel如何把顺序倒过来_在excel中怎么使文字颠倒顺序反过来显示呢? 2019-04-21
php正则表达式获取图片路径,php 常用正则表达式实例(图片地址,与指定内容获取)... 2019-04-21
脚本语言php是什么意思,PHP脚本语言 2019-04-21
matlab数学规划模型,数学规划模型 2019-04-21
视频提取音频php,如何提取视频中的音频,从视频文件中提取出音频输出成MP3格式... 2019-04-21
diy.php添加验证码,织梦dedecms自定义表单中加入验证码 2019-04-21
在php脚本中 通过可以获取,在PHP中,可以使用Unix时间戳获取精确的脚本执行时间。... 2019-04-21
s2-045 php exp,S2-045-EXP.py --Struts2任意代码执行漏洞 (S2-045,CVE-2017-5638) 2019-04-21
linux sdk 窗口句柄,Venus: 针对Linux平台上,对常用的系统API进行面向对象的封装SDK。... 2019-04-21
c语言程序设计 科学出版社习题答案,C语言程序设计(科学出版社)第4章 课后习题参考答案.doc... 2019-04-21
c语言 无错 但只运行一半,求哈夫曼编码时程序运行到一半就终止了,编译无错... 2019-04-21
deepin linux 2014安装,2014.2版本的Deepin虚拟机安装浅谈(就是深度Linux) 2019-04-21
android 限速工具,Android下载器之限速篇 2019-04-21
html刷新ajax实现原理,AJAX的原理—如何做到异步和局部刷新 2019-04-21
html中列表菜单加文字请选择,html中下拉菜单 2019-04-21
读书郎平板中android,读书郎学生平板电脑怎么用 使用方法详解【图文】 2019-04-21