我们只知道不同的语言解密要相互通用,就需要遵循相同的加密方式,然而在具体做技术预研的时候,就发现会遇到很多问题,网上找的资料也是比较片面,所以我踩了坑,并且把解决方案和相关资料源码提供出来,给需要的朋友一些参考。

场景:网页客户端(html)页面通过在发起请求时,将数据加密发送给C#编写的后端。C#后端接受到数据后需要进行解密,解密后得到明文,用明文进行业务操作,操作完成后,将结果加密返回。

因为C#后端使用的是DES CBC模式,所以前端JS也要使用相同的方式。否则加密解密结果不以言,就无法互通了。

使用技术:

1.前端javascript 使用CryptoJS进行加解密。

2.使用System.Security.Cryptography 命名空间下的相关类。

前端核心代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JS_DES加解密CBC模式与C#DES加解密相同互通</title>
<script type="text/javascript">
function CBCJiami() {
var key = $("#desKey").val();
var iv = $("#desIV").val();
var msg = $("#source").val();
var dd = encryptByDES(msg, key, iv);
$("#JiaMiHou").val(dd);
$("#target").val(toBase641(dd));
}
function CBCJiemi() {
var key = $("#desKey").val();
var iv = $("#desIV").val();
var msg = $("#JiaMiHou").val();
var dd = decryptByDESModeEBC(msg, key, iv);
$("#CBCJiemi").val(dd);
}
// DES CBC模式加密
//加密内容、秘钥、向量
function encryptByDES(message, key, iv) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var ivHex = CryptoJS.enc.Utf8.parse(iv);
encrypted = CryptoJS.DES.encrypt(message, keyHex, {
iv: ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
return encrypted.ciphertext.toString();
}
//DES CBC模式解密
function decryptByDESModeEBC(ciphertext, key, iv) {
//把私钥转换成UTF - 8编码的字符串
var keyHex = CryptoJS.enc.Utf8.parse(key);
var ivHex = CryptoJS.enc.Utf8.parse(iv);
// direct decrypt ciphertext
var decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse(ciphertext)
}, keyHex, {
iv: ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
//十六进制字符串转为base64
function toBase641(input) {
var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64_rep = "";
var cnt = 0;
var bit_arr = 0;
var bit_num = 0;
for (var n = 0; n < input.length; ++n) {
if (input[n] >= 'A' && input[n] <= 'Z') {
ascv = input.charCodeAt(n) - 55;
}
else if (input[n] >= 'a' && input[n] <= 'z') {
ascv = input.charCodeAt(n) - 87;
}
else {
ascv = input.charCodeAt(n) - 48;
}
bit_arr = (bit_arr << 4) | ascv;
bit_num += 4;
if (bit_num >= 6) {
bit_num -= 6;
base64_rep += digits[bit_arr >>> bit_num];
bit_arr &= ~(-1 << bit_num);
}
}
if (bit_num > 0) {
bit_arr <<= 6 - bit_num;
base64_rep += digits[bit_arr];
}
var padding = base64_rep.length % 4;
if (padding > 0) {
for (var n = 0; n < 4 - padding; ++n) {
base64_rep += "=";
}
}
return base64_rep;
}
</script>
<script src="jquery-3.4.1.min.js"></script>
<script src="CryptoJS v3.1.2/rollups/tripledes.js"></script>
<script src="CryptoJS v3.1.2/components/mode-ecb-min.js"></script>
<script src="Base64Helper.js"></script>
</head>
<body>
<div>
<fieldset>
<legend>DES CBC模式加密</legend>
Key:<input type="text" id="desKey" value="z9j#$@4D">
<br />
IV:<input type="text" id="desIV" value="x34dg!df">
<br />
MSG:<input id="source" value="{}" />
<br />
<input type="button" onclick="CBCJiami();" name="" value="CBC加密" />
<br />
加密后:<input id="JiaMiHou" value="" />
<br />
转base64后:<input id="target" value="" />
<br />
<input type="button" onclick="CBCJiemi();" name="" value="CBC解密" />
<br />
解密后:<input id="CBCJiemi" value="" />
</fieldset>
</div>
</body>
</html>

后端核心代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks; namespace WindowsFormsTest
{
public class DESHelper
{
/// <summary>
/// DES加密字符串
/// </summary>
/// <param name="encryptString">待加密的字符串</param>
/// <param name="encryptKey">加密密钥,要求为8位</param>
/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
public static string EncryptDES(string encryptString, string encryptKey, string iv)
{
try
{
//将字符转换为UTF - 8编码的字节序列
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
byte[] rgbIV = Encoding.UTF8.GetBytes(iv);
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
//用指定的密钥和初始化向量创建CBC模式的DES加密标准
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
dCSP.Mode = CipherMode.CBC;
dCSP.Padding = PaddingMode.PKCS7;
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);//写入内存流
cStream.FlushFinalBlock();//将缓冲区中的数据写入内存流,并清除缓冲区
return Convert.ToBase64String(mStream.ToArray()); //将内存流转写入字节数组并转换为string字符
}
catch
{
return encryptString;
}
} /// <summary>
/// DES解密字符串
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
public static string DecryptDES(string decryptString, string decryptKey, string iv)
{
try
{
//将字符转换为UTF - 8编码的字节序列
byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey.Substring(0, 8));
byte[] rgbIV = Encoding.UTF8.GetBytes(iv);
byte[] inputByteArray = Convert.FromBase64String(decryptString);
//用指定的密钥和初始化向量使用CBC模式的DES解密标准解密
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
dCSP.Mode = CipherMode.CBC;
dCSP.Padding = PaddingMode.PKCS7;
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Encoding.UTF8.GetString(mStream.ToArray());
}
catch
{
return decryptString;
} }
}
}

  运行效果:

 其中要注意一点:前端加密后有个转Base64的操作,加密解密后才会相同,原因是C#加密后的数据是转成base64的。

多说无益,直接上代码:

链接:https://pan.baidu.com/s/1FqpRa9LGuSfRZ9ZZ7Hau0g
提取码:hjvu

最后感谢网络上我参考过的文章、博客。有的代码是直接抄过来改的,参考太多无法一一列出,但要感谢他们无私精神。

javascript JS CryptoJS DES加解密CBC模式与C#DES加解密相同互通的更多相关文章

  1. DES加解密 cbc模式 的简单讲解 && C++用openssl库来实现的注意事项

    DES cbc是基于数据块加密的.数据块的长度为8字节64bit.以数据块为单位循环加密,再拼接.每个数据块加密的秘钥一样,IV向量不同.第一个数据快所需的IV向量,需要我们提供,从第二个数据块开始, ...

  2. C++调用openssl实现DES加密解密cbc模式 zeropadding填充方式 pkcs5padding填充方式 pkcs7padding填充方式

    ============================================== des   cbc  加密 zeropadding填充方式 ======================= ...

  3. C++ 使用openssl库实现 DES 加密——CBC模式 && RSA加密——公加私解——私加公解

    之前工作上需要用C++把软件生成的用户序列号用des加密cbc的模式,加密后为二进制,转化为十六进制,然后提供给java写的授权码管理平台. java平台会根据用户序列号,生成一个授权码,授权码是用r ...

  4. Android DES加密的CBC模式加密解密和ECB模式加密解密

    DES加密共有四种模式:电子密码本模式(ECB).加密分组链接模式(CBC).加密反馈模式(CFB)和输出反馈模式(OFB). CBC模式加密: import java.security.Key; i ...

  5. 解决AES算法CBC模式加密字符串后再解密出现乱码问题

    问题 在使用 AES CBC 模式加密字符串后,再进行解密,解密得到的字符串出现乱码情况,通常都是前几十个字节乱码: 复现 因为是使用部门 cgi AESEncryptUtil 库,找到问题后,在这里 ...

  6. php AES cbc模式 pkcs7 128位加密解密(微信小程序)

    PHP AES CBC模式PKCS7 128位加密 加密: $key = '1234567812345678'; $iv = '1234567890123456'; $message = '12345 ...

  7. PHP 3DES 加解密(CBC模式,pkcs5padding填充)

    1.前言:项目中接入第三方支付遇到3DES加密,以前也没用过,搜了好多,都不适用,各种不对,后来自己结合搜到的终于弄正确了,检测地址:http://tool.chacuo.net/crypt3des. ...

  8. [编码解码] 关于AES加解密中CBC模式的IV初始化向量的安全性问题

    copy from : https://www.jianshu.com/p/45848dd484a9 前段时间,在研究HLS的AES加密,由于一个地方电视台的HLS流有AES加密,在查看了相关的加解密 ...

  9. AES加密CBC模式兼容互通四种编程语言平台【PHP、Javascript、Java、C#】

    原文:AES加密CBC模式兼容互通四种编程语言平台[PHP.Javascript.Java.C#] 由于本人小菜,开始对AES加密并不了解,在网络上花了比较多时间查阅资料整理: 先简单从百度找来介绍: ...

随机推荐

  1. 关于HTML的引入CSS文件问题

    一 html代码引用外部css文件时若css文件在本文件的父目录下的其他目录下,可使用绝对路径.此时路径要写为  “ ../ ”形式,如在tomcat下建立一个test文件,在该文件中建立两个文件 夹 ...

  2. java基础知识总结,绝对经典

    写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java语言代码把思路体现出来. 学习新技 ...

  3. java volatile关键字作用及使用场景

    1. volatile关键字的作用:保证了变量的可见性(visibility).被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象.如以下代码片段,isShut ...

  4. java并发笔记之四synchronized 锁的膨胀过程(锁的升级过程)深入剖析

    警告⚠️:本文耗时很长,先做好心理准备,建议PC端浏览器浏览效果更佳. 本篇我们讲通过大量实例代码及hotspot源码分析偏向锁(批量重偏向.批量撤销).轻量级锁.重量级锁及锁的膨胀过程(也就是锁的升 ...

  5. JDK1.8源码分析01之学习建议(可以延伸其他源码学习)

    序言:目前有个计划就是准备看一下源码,来提升自己的技术实力.同时现在好多面试官都喜欢问源码,问你是否读过JDK源码等等? 针对如何阅读源码,也请教了我的老师.下面就先来看看老师的回答,也许会有帮助呢. ...

  6. 用jquery实现放大镜效果

    ----css代码--- *{margin:0;padding:0;} .showimg{position:relative;width:450px;height:420px;border:1px s ...

  7. 逆向破解之160个CrackMe —— 001

    CrackMe —— 001 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  8. 七天学会NodeJS——第一天

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:http://nqdeng.github.io/7-days-nodejs Node.js 是一个能 ...

  9. 伪分布式Spark + Hive on Spark搭建

    Spark大数据平台有使用一段时间了,但大部分都是用于实验而搭建起来用的,搭建过Spark完全分布式,也搭建过用于测试的伪分布式.现在是写一遍随笔,记录一下曾经搭建过的环境,免得以后自己忘记了.也给和 ...

  10. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...