DES 加密 解密

EncryptUtil

feiyangklDES

一行代码完成DES加密,加密模式 DES + CBC

DEMO GIF

895324-20161021184549451-872168921.gif

DEMO 简介

最近项目中用到DES加密,在这里整理成篇,供大家参考阅读,在使用该demo过程中,你可能会遇到一些问题,首先你需要看一下下面的demo简介,看看该demo 是否适合你的项目。项目中的DES加解密主要用在网络请求过程中对上传的参数进行加密,对从后台服务器获取的数据进行解密。整体的加密流程为:加密的过程: 参数字典 --> json字符串 --> base64加密后的字符串 --> DES加密后base64再加密 --> 输出最终加密后的字符串;解密的过程: 后台服务器获取加密的字符串 -->base64解密 --> DES解密后base64解密 --> json字符串 --> 数据字典;(与加密的过程相反)网上对DES的详细介绍已经有很多,在这里不做赘述,如果你需要了解这些知识,google.
我们公司后台为JAVA,移动端有iOS与Android, 讨论后选择DES的加密模式为 DES + CBC (注意是否满足你的加密需求)。为什么选择这种加密模式:如果采用PKCS7Padding或者PKCS5Padding这种加密方式,末端添加的数据可能不固定,在解码后需要把末端多余的字符去掉,比较棘手。如果不管补齐多少位,末端都是'\0',去掉的话比较容易操作。 最主要的是能使得iOS/Android/PHP相互通信,也是加密过程中最难搞的地方,尤其需要开发者注意。项目中用到了 google 的 base64 加解密库 GTMBase64,但是这个库已经有很多年没有更新 还是 MRC 开发模式,需要手动配置一下:1.选择项目中的Targets,选中你所要操作的Target,2.选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并在输入框中输入 -fno-objc-arc

DEMO 使用示例

//加密/// 加密
NSMutableDictionary *dic=[NSMutableDictionary dictionary];
[dic setValue:@"111111" forKey:@"password"];
[dic setValue:@"admin" forKey:@"userName"];/*
加密{"userName":"admin","password":"111111"}和
{
"userName" : "admin",
"password" : "111111"
}
加密后结果是不一样的,一定要确定公司后台是怎么加密的,要不然有可能会错误
*/
NSString *jsonstr = [dic JSONString];
self.lb_show.text = [EncryptUtil encryptUseDES:jsonstr key:gkey];//加密结果 iMXucxT4Z6v0ZILRJtUX1W/8KfR1wvqqdDxHiOdfTvkdVQQnJ7p1DdMPQXM60BwNHBdjhTqbnXIN
eEYVIHbb6w==
//解密- (IBAction)clickDecodeBtn:(UIButton *)sender {//上面加密的结果
NSString *AESString = @"iMXucxT4Z6v0ZILRJtUX1W/8KfR1wvqqdDxHiOdfTvkdVQQnJ7p1DdMPQXM60BwNHBdjhTqbnXIN
eEYVIHbb6w==";///解密
self.lb_show.text = [EncryptUtil decryptUseDES:self.lb_show.text key:gkey];解密结果:{"userName":"admin","password":"111111"}}
java 
/**
* <li>
* 方法名称:encrypt</li> <li>
* 加密方法
* @param xmlStr
*            需要加密的消息字符串
* @return 加密后的字符串
*/
public static String encrypt(String xmlStr) {
byte[] encrypt = null;try {
// 取需要加密内容的utf-8编码。
encrypt = xmlStr.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 取MD5Hash码,并组合加密数组
byte[] md5Hasn = null;
try {//            md5Hash = EncryptUtil.MD5Hash(temp, 16, temp.length - 16);md5Hasn = EncryptUtil.MD5Hash(encrypt, 0, encrypt.length);
} catch (Exception e) {
e.printStackTrace();
}
// 组合消息体
byte[] totalByte = EncryptUtil.addMD5(md5Hasn, encrypt);// 取密钥和偏转向量
byte[] key = new byte[8];
byte[] iv = new byte[8];
getKeyIV(EncryptUtil.key, key, iv);SecretKeySpec deskey = new SecretKeySpec(key, "DES");IvParameterSpec ivParam = new IvParameterSpec(iv);// 使用DES算法使用加密消息体
byte[] temp = null;
try {
temp = EncryptUtil.DES_CBC_Encrypt(totalByte, deskey, ivParam);
} catch (Exception e) {
e.printStackTrace();
}// 使用Base64加密后返回
return new BASE64Encoder().encode(temp);
}ios
/// 加密方法
+ (NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key
{
/// 转换成data
NSData* plainTextdata = [plainText dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger plainTextdatLength = [plainTextdata length];
/// 将data数据MD5加密
unsigned char digest[16];
CC_MD5([plainTextdata bytes],(CC_LONG) plainTextdatLength, digest);// 总长度 MD5 + plainText
NSUInteger plainTextBufferTotalSize  = 16 +plainTextdatLength;// 将plainText 转换成bytes
Byte *testByte = (Byte *)[plainTextdata bytes];// 定义totalByte
Byte totalByte[plainTextBufferTotalSize];for (int i = 0; i < plainTextBufferTotalSize; ++i) {
if (i<16) {
totalByte[i] =digest[i];
}else{
totalByte[i] =testByte[i - 16];
}
}/// 将key base64 编码
NSData *baseKey = [GTMBase64 decodeString:key];
Byte *buf = (Byte *)[baseKey bytes];Byte key1[8];
Byte iv2[8];
for (int i = 0; i < 8; i++) {key1[i] = buf[i];
}
//    // 后8位为iv向量
for (int i = 0; i < 8 ; i++) {
iv2[i] = buf[i + 8];
}NSString *ciphertext = nil;
unsigned char buffer[1024];
memset(buffer, 0, sizeof(char));
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
key1,
kCCKeySizeDES,
iv2,
totalByte,
plainTextBufferTotalSize,
buffer,
1024,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
ciphertext = [[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding];
}
return ciphertext;
}

java 解密
/**
* <li>
* 方法名称:encrypt</li> <li>
* 功能描述:
*
* <pre>
* 解密方法
* </pre>
*
* </li>
*
* @param xmlStr
*            需要解密的消息字符串
* @return 解密后的字符串
* @throws Exception
*/
public static String decrypt(String xmlStr) throws Exception {
// base64解码
BASE64Decoder decoder = new BASE64Decoder();
byte[] encBuf = null;
try {
encBuf = decoder.decodeBuffer(xmlStr);
} catch (IOException e) {
e.printStackTrace();
}// 取密钥和偏转向量
byte[] key = new byte[8];
byte[] iv = new byte[8];
getKeyIV(EncryptUtil.key, key, iv);SecretKeySpec deskey = new SecretKeySpec(key, "DES");
IvParameterSpec ivParam = new IvParameterSpec(iv);// 使用DES算法解密
byte[] temp = null;
try {
temp = EncryptUtil.DES_CBC_Decrypt(encBuf, deskey, ivParam);
} catch (Exception e) {
e.printStackTrace();
}// 进行解密后的md5Hash校验
byte[] md5Hash = null;
try {
md5Hash = EncryptUtil.MD5Hash(temp, 16, temp.length - 16);
} catch (Exception e) {
e.printStackTrace();
}// 进行解密校检
for (int i = 0; i < md5Hash.length; i++) {
if (md5Hash[i] != temp[i]) {
// System.out.println(md5Hash[i] + "MD5校验错误。" + temp[i]);
throw new Exception("MD5校验错误。");
}
}// 返回解密后的数组,其中前16位MD5Hash码要除去。
return new String(temp, 16, temp.length - 16, "utf-8");
}ios 解密/// 解密方法
+ (NSString *) decryptUseDES:(NSString *)plainText key:(NSString *)key {// plainTextData转换 base64
NSData *BasePlainTextData = [GTMBase64 decodeString:plainText];
// 将BasePlainTextDatabase64转换为byte数组
Byte *BasePlainTextDataByte = (Byte *)[BasePlainTextData bytes];// 将key base64解码
NSData *baseKey = [GTMBase64 decodeString:key];
// 将key 转换成 byte数组
Byte *buf = (Byte *)[baseKey bytes];// 定义key iv byte数组
Byte keyByte[8];
Byte ivByte[8];
for (int i = 0; i < 8; i++) {
keyByte[i] = buf[i];
}
//    // 后8位为iv向量
for (int i = 0; i < 8 ; i++) {
ivByte[i] = buf[i + 8];
}/// 返回值长度
size_t bufferSize = BasePlainTextData.length;// 字符串长度比较长 返回值给大点
unsigned char buffer[1024];
memset(buffer,0,sizeof(char));
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
keyByte,
kCCKeySizeDES,
ivByte,
BasePlainTextDataByte,
bufferSize,
buffer,
1024,
&numBytesEncrypted);NSData *resultdata;
if (cryptStatus == kCCSuccess) {resultdata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
}Byte *resultByte = (Byte *)[resultdata bytes];// 返回数组长度 减去MD5加密的16
size_t returnLength = resultdata.length - 16;
/// 定义
Byte decryptionByte[returnLength];for (int i = 0; i < returnLength; ++i) {
decryptionByte[i] = resultByte[i+16];
}/// md5 校验
//    unsigned char digest[16];
//    CC_MD5(decryptionByte,returnLength, digest);
//    NSData *md5data = [NSData dataWithBytes:digest length:16];// 进行解密校检
//    Byte *md5bte= (Byte *)[md5data bytes];//    for (int i = 0; i < 40; i++) {
//
//
//        if (md5bte[i] !=decryptionByte[i] ) {
//            // System.out.println(md5Hash[i] + "MD5校验错误。" + temp[i]);
//            //            throw new Exception("MD5校验错误。");
//
//            NSLog(@"c1111uowu");
//        }else{
//            NSLog(@"cuowu");
//        }
//    }NSData *namedata = [[NSData alloc] initWithBytes:decryptionByte length:returnLength];NSString *str = [[NSString alloc] initWithData:namedata encoding:NSUTF8StringEncoding];
NSLog(@"%@",str);return str;}

项目中遇到的一些坑,在 DEMO 中都已经注释出来,写的比较清楚,如果该 DEMO 帮助了您,也希望能给个 star

鼓励一下,如果在使用中您有任何问题,可以在 github issues,我会尽自己能力给您答复 。

在这里感谢这些 blog 的作者,让我在开发过程中少走了很多弯路:[http://www.open-open.com/lib/view/open1452738808948.html)[https://my.oschina.net/jsan/blog/54385)[http://blog.csdn.net/j_akill/article/details/44079597](http://blog.csdn.net/j_akill/article/details/44079597)[http://blog.csdn.net/jbjwpzyl3611421/article/details/18256917)[https://github.com/IMCCP/CCPAESEncode/blob/master/CCPAESEncode)

转载于:https://www.cnblogs.com/feiyangkl/p/5985753.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bootstrap带有下拉按钮的输入框_关于bootstrap--表单(下拉select、输入框input、文本域textare复选框checkbox和单选按钮radio)...

html 里面的 role 本质上是增强语义性&#xff0c;当现有的HTML标签不能充分表达语义性的时候&#xff0c;就可以借助role来说明。通常这种情况出现在一些自定义的组件上&#xff0c;这样可增强组件的可访问性、可用性和可交互性。role的作用是描述一个非标准的tag的实际作用。…

CSS3 线性渐变背景的过渡效果

对于background-color&#xff0c;可以直接transition: background-color 2s就能实现过渡效果&#xff0c;但对于background:-webkit-radial-gradient(circle,#ffc71d 0,rgba(168,117,14,.5) 130%);就无能为力了。对于这种复杂的背景&#xff0c;只能给opacity添加过渡效果了&a…

markdown绘图插件----mermaid简介

作者&#xff1a;黄永刚 mermaid简介 当撰写文档的时候&#xff0c;对于流程图的生成大多使用Visio等繁重的工具&#xff0c;没有一种轻便的工具能够画图从而简化文档的编写&#xff0c;就像markdown那样。 mermaid解决这个痛点&#xff0c;这是一个类似markdown语法的脚本语言…

华为三层交换机路由配置案例_华为三层交换机配置实例

1华为三层交换机配置实例一例服务器1双网卡&#xff0c;内网IP:&#xff0c;其它计算机通过其代理上网PORT1属于VLAN1PORT2属于VLAN2PORT3属于VLAN3VLAN1的机器可以正常上网配置VLAN2的计算机的网关为&#xff1a;配置VLAN3的计算机的网关为&#xff1a;即可实现VLAN间互联如果…

大学只待成追忆,只是工作已半年,2016再见

时光匆匆&#xff0c;真的不知不觉&#xff0c;已经毕业半年。这一年发生了好多事&#xff0c;回望简直难以相信。 再见广州&#xff0c;你好厦门 广深工作好找&#xff0c;但心就是想离开&#xff0c;当时想的是&#xff0c;找一个地方&#xff0c;让一切重新开始。来到厦门…

centos7挂载nas存储_CentOS7搭建NAS文件共享存储

概述&#xff1a;NFS是一种基于TCP/IP传输的网络文件系统协议&#xff0c;最初由SUN公司开发。通过NFS协议&#xff0c;客户机可以像访问本地目录一样访问远程服务器中的共享资源。NFS得到了如NAS等网络存储的设备极好支持。也是LVS共享存储的首选。环境&#xff1a;CentOS 7.8…

【移动端html5】 android video播放进度精确控制

android上视频播放存在的问题 在PC上播放html5视频&#xff0c;设置video.currentTime5,视频将跳到5s的位置&#xff0c;并且显示出第5s的画面。在安卓下&#xff0c;却存在下面两个问题&#xff1a; 在安卓上&#xff0c;为了省电&#xff0c;在暂停的时候&#xff0c;改变视…

柯理化

在JS中柯里化就是把一个需要传入多个参数的函数变成多个嵌套的只要传入一个参数的函数 在普通函数中的柯理化&#xff1a; var addfunction(x,y){ return xy; } 柯里化&#xff1a; var addCurringfunction(x){ return function(y){ return xy; } } addCurring(1)(2);//3 如果是…

Java NIO 教程

NIO 概述 NIO有三个核心组件&#xff1a; 通道&#xff08;Channels&#xff09;缓冲器&#xff08;Buffers&#xff09;选择器&#xff08;Selectors&#xff09; 实际上&#xff0c;NIO的组件和类远不止这三个&#xff0c;但这个三个组件是核心。至于其它组件&#xff0c;…

threejs相机和渲染器

渲染器 渲染器其实代表的是canvas标签。 渲染器的类型 WebGLRender 使用WebGL来渲染图形&#xff0c;速度较快&#xff0c;但是有些机器不支持WebGL。 CanvasRender 使用canvas2d来渲染图形&#xff0c;在较老的版本上&#xff0c;主要是用来渲染2D图形。现在这个渲染器在…

类的 三大特性 封装,继承,多态 overload与override的区别

OOP三大特性&#xff1a;封装&#xff0c;继承&#xff0c;多态 封装的目的&#xff1a;为了让类更安全封装的做法&#xff1a;1.类里面的成员变量做为private2.使用成员方法来间接访问成员变量3.在该方法里面加限制条件 php类里面不允许出现同名方法 继承 概念&#xff1a;子类…

三级菜单 python_python三级菜单

menu {北京:{海淀:{五道口:{soho:{},网易:{},google:{}},中关村:{爱奇艺:{},汽车之家:{},youku:{},},上地:{百度:{},},},昌平:{沙河:{老男孩:{},北航:{},},天通苑:{},回龙观:{},},朝阳:{},东城:{},},上海:{闵行:{"人民广场":{炸鸡店:{}}},闸北:{火车战:{携程:{}}},浦…

threejs概览

threejs术语和概念 threejs的API很长&#xff0c;有很多概念和术语&#xff0c;理解了这些概念和术语&#xff0c;才能更好的使用threejs。这些概念和术语都藏在API右侧的大纲中&#xff0c;下图简单整理了一下这些概念&#xff1a; 这些概念又分为四个大类&#xff08;见上图…

C#生成新浪微博短网址 示例源码

using System;using System.Collections.Generic;using System.Linq;using System.Text;using DotNetSample.Models;using System.Web.Script.Serialization;namespace DotNetSample.Utils{public class ShortUrlHelper{/// <summary>/// 获取新浪短域名/// </summary…

leetcode数组汇总_[LeetCode] 300. 最长上升子序列

题目链接&#xff1a; https://leetcode-cn.com/problems/longest-increasing-subsequence难度&#xff1a;中等通过率&#xff1a;43.0%题目描述:给定一个无序的整数数组&#xff0c;找到其中最长上升子序列的长度。示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释:…

threejs创建平面几何形状

创建平面几何形状 平面几何形状有三种&#xff1a;点&#xff0c;线&#xff0c;面三种&#xff0c;下面说说用threejs创建这几种形状的方法。 创建点 创建点可以使用Points类。 function createPoints(){//创建一个Geometry&#xff0c;并添加点let geometry new THREE.G…

新建vue3项目(未完待续)

vite 官网 https://cn.vitejs.dev/ 使用 vite 创建项目 npm create vitelatest 进入目录后 执行 npm install 运行程序 npm run dev vscode 不要同时安装 vetur 和 volar 关于安装eslint 官网 &#xff1a;https://eslint.org 安装ESLINT npm install eslint …

wcf 返回图片_wcf http 返回图片

做项目时候用wcf 返回图片,从官网上找了找一次只能返回一张图片&#xff0c;但是一直查不到返回多个图片的方法&#xff0c;ios 可以异步加载看速度也可以&#xff0c;先记录一下等以后用解决了再发[ServiceContract]public interface IImageServer{[OperationContract, WebGet…

threejs精灵(Sprite)

Sprite精灵 Sprite叫精灵&#xff0c;计算机图形学中&#xff0c;精灵指包含于场景中的二维图像或动画&#xff08;wiki&#xff09;。在threejs中&#xff0c;这样说明Sprtite&#xff08;doc&#xff09; : A sprite is a plane that always faces towards the camera , ge…

Ubuntu更改鼠标灵敏度

需要命令:xinput 清自行用 man xinput 查询 xinput 帮助文档 1、插入鼠标&#xff0c;打开终端&#xff0c;输入命令&#xff1a;xinput 查询当前已挂在设备 2、拔出鼠标&#xff0c;打开终端&#xff0c;再输入命令&#xff1a;xinput 查询当前已挂在设备&#xff0c;发现缺少…