Golang实现ECB模式3DES算法

news/2023/12/9 16:19:35

简介

因项目需要使用ECB模式下的3DES算法加解密信息,golang默认只提供CBC模式,只能自己实现ECB模式。
参考https://segmentfault.com/a/11...,文章对ECB模式的DES有解释,并实现了部分DES算法样例。这里把算法补全,提供3DES算法实现。

基础

3DES
3DES算法就是采用一个长度为24字节的密钥,将密钥分成各8字节的3份子密钥:K1、k2、k3。使用这3个密钥对明文进行加密、解密处理,如下:
E(k,d)、D(k,d)分别表示使用密钥k对数据d进行加密或解密,返回加密或解密后的数据。

3DES加密过程:
E(k3,D(k2,E(k1,d)))
意思为:将明文d先用k1加密,得到密文d1;对d1再用k2做解密处理,得到密文d2;再对d2用k3做加密处理,得到最终密文。
3DES解密过程与加密相反:
D(k1,E(k2,D(k3,d)))
意思为:将密文d先用k3解密,得到密文d1;对d1再用k2做加密处理,得到密文d2;再对d2用k1做解密处理,得到最终明文。

填充
填充方式采用PKCS5Padding,代码照搬如下:

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

func PKCS5Unpadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}

填充过程就是要把明文长度凑成8的整数倍,少几个就填充几个对应的数字。如少4个字节才满8的倍数,那就填充4个0x04;如果明文刚好是8的倍数,就要再填充8个0x08。
解密后,要把填充的数据删除,就取最后一个字节的值,按值删掉最后几个字节。(设计的很巧妙)

代码

完整的代码:

package tripledesecb
import (
    "bytes"
    "crypto/des"
    "errors"
    "fmt"
    "golang.org/x/crypto/pbkdf2"
)

//ECB PKCS5Padding
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

//ECB PKCS5Unpadding
func PKCS5Unpadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}

//Des加密
func encrypt(origData, key []byte) ([]byte, error) {
    if len(origData) < 1 || len(key) < 1 {
        return nil, errors.New("wrong data or key")
    }
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    bs := block.BlockSize()
    if len(origData)%bs != 0 {
        return nil, errors.New("wrong padding")
    }
    out := make([]byte, len(origData))
    dst := out
    for len(origData) > 0 {
        block.Encrypt(dst, origData[:bs])
        origData = origData[bs:]
        dst = dst[bs:]
    }
    return out, nil
}

//Des解密
func decrypt(crypted, key []byte) ([]byte, error) {
    if len(crypted) < 1 || len(key) < 1 {
        return nil, errors.New("wrong data or key")
    }
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    out := make([]byte, len(crypted))
    dst := out
    bs := block.BlockSize()
    if len(crypted)%bs != 0 {
        return nil, errors.New("wrong crypted size")
    }

    for len(crypted) > 0 {
        block.Decrypt(dst, crypted[:bs])
        crypted = crypted[bs:]
        dst = dst[bs:]
    }

    return out, nil
}

//[golang ECB 3DES Encrypt]
func TripleEcbDesEncrypt(origData, key []byte) ([]byte, error) {
    tkey := make([]byte, 24, 24)
    copy(tkey, key)
    k1 := tkey[:8]
    k2 := tkey[8:16]
    k3 := tkey[16:]

    block, err := des.NewCipher(k1)
    if err != nil {
        return nil, err
    }
    bs := block.BlockSize()
    origData = PKCS5Padding(origData, bs)

    buf1, err := encrypt(origData, k1)
    if err != nil {
        return nil, err
    }
    buf2, err := decrypt(buf1, k2)
    if err != nil {
        return nil, err
    }
    out, err := encrypt(buf2, k3)
    if err != nil {
        return nil, err
    }
    return out, nil
}

//[golang ECB 3DES Decrypt]
func TripleEcbDesDecrypt(crypted, key []byte) ([]byte, error) {
    tkey := make([]byte, 24, 24)
    copy(tkey, key)
    k1 := tkey[:8]
    k2 := tkey[8:16]
    k3 := tkey[16:]
    buf1, err := decrypt(crypted, k3)
    if err != nil {
        return nil, err
    }
    buf2, err := encrypt(buf1, k2)
    if err != nil {
        return nil, err
    }
    out, err := decrypt(buf2, k1)
    if err != nil {
        return nil, err
    }
    out = PKCS5Unpadding(out)
    return out, nil
}

上面的代码,稍微改一下就可以开放出ecb模式的des算法,我用不上,就没放出来。

刚开始用golang,也是第一次在segmentfault上发文,轻拍!


http://www.niftyadmin.cn/n/3315041.html

相关文章

VUE学习---------class样式三种定义方式

效果&#xff0c;上面三种定义的样式都成功显示出来了

LAMP - Apache用户认证

有些时候我们只想让自己去访问网站的某一个文件或者目录&#xff0c;不让其他用户有权限去访问&#xff0c;那么就需要在服务器上去配置一下。假设网站的根目录是/data/www, 新建了一个子目录为/data/www/abc目录&#xff0c;对于在这个abc目录下的文件除了我们自己&#xff0c…

java中抽象类和接口的异同(原文作者:博客园 海子)

深入理解Java的接口和抽象类 深入理解Java的接口和抽象类 对于面向对象编程来说&#xff0c;抽象是它的一大特征之一。在Java中&#xff0c;可以通过两种形式来体现OOP的抽象&#xff1a;接口和抽象类。这两者有太多相似的地方&#xff0c;又有太多不同的地方。很多人在初学的时…

VUE学习-----------router路由

1.创建pages目录&#xff0c;在下面创建3个vue页面 2.创建路由组件router.js 路由js代码 import Vue from vue; import VueRouter from vue-router //引入自定页面 import pageA from ./pages/a.vue import pageB from ./pages/b.vue import index from ./pages/index.vue //使…

关于WebMvcConfigurerAdapter过期,使用新的WebMvcConfigurationSupport

最近在Spring Boot项目中使用WebMvcConfigurerAdapter时&#xff0c;编译器提示我该类已经被遗弃&#xff0c;查询资料发现需要使用新的WebMvcConfigurationSupport。 在使用过程中遇到的问题&#xff0c;解决后供大家参考&#xff01; Configuration public class WebAppCon…

Openfire的启动过程与session管理

说明本文源码基于Openfire4.0.2。Openfire的启动Openfire的启动过程非常的简单&#xff0c;通过一个入口初始化lib目录下的openfire.jar包&#xff0c;并启动一个XMPPServer实例。下面就是ServerStarter.start方法的代码片断&#xff1a;Class containerClass loader.loadClas…

springboot中mybatis打印sql语句的方法

如果使用的是application.properties文件&#xff0c;加入如下配置&#xff1a; logging.level.com.example.demo.daodebug logging.level.com&#xff0c;后面的路径指的是mybatis对应的方法接口所在的包。 并不是mapper.xml所在的包。 如果使用的是application.yml文件&am…

CentOS学习之常用命令ls

命令格式与目录处理命令ls 命令格式: 命令[-选项][参数] 例如: ls -la /etc 说明: 1)个别命令使用不遵循此格式 2)当多个选项时&#xff0c;可以写在一起 3)简化选项与完整选项 -a 等于--all PS&#xff1a;在Linux中“.”代表的是隐藏文件。 目录处理命令&#xff1a;ls 命…

OJ题:将一个字符串顺序翻转

题目描述 写出一个程序&#xff0c;接受一个字符串&#xff0c;然后输出该字符串反转后的字符串。 之前写过这样的一个程序&#xff0c;用位运算的方法去操作指针&#xff0c;但是那样的方法未免就有点复杂啦&#xff0c;不如用以下这种&#xff0c;简单明了。 程序如下&#x…

20、30、40岁年轻人,2020年的建议

相信我&#xff0c;认真看完&#xff0c;不亏。让我们先了解一下陆奇&#xff1a; 这几年陆奇被格外关注&#xff0c;始于2017年1月17日他被百度任命为百度总裁。这次任命份量极高&#xff0c;到今天百度创立19年&#xff0c;李彦宏给出如此高的权力&#xff0c;陆奇是唯一一个…

cnpm不是内部命令 cnpm: command not found 的解决

【问题】bash: cnpm: command not found command not found这种问题一般有两个原因&#xff1a; 1、命令没有安装成功 2、环境变量没有配置 【解决】配置环境变量 1、前提是安装了cnpm npm install -g cnpm --registryhttps://registry.npm.taobao.org 以上输出表示安装成功 …

tableIView 区头的一点问题

要记得设置区头的高度 否则会出现第一行没区头问题转载于:https://www.cnblogs.com/dlwj/p/5753902.html

Oracle12c删除pdb容器数据库

一、dbca进入到图形化界面 二、选择“删除插接式数据库” 三、选择pdb所在的数据库&#xff0c;这里是ORCL 注意&#xff1a;这里需要保证数据库服务和监听服务是开启状态。 四、选择需要删除的pdb&#xff0c;这里选择的是YKCHR 五、概要信息 六、开始删除 七、删除完成 八、…

Win7系统右键上下文菜单与计算机界面中其他类型快捷方式的清理

2019独角兽企业重金招聘Python工程师标准>>> 我使用的操作系统为Win7旗舰版。前几天我卸载了电脑中的115浏览器&#xff0c;不过卸载后我发现了两个残留项。 第一个问题是使用鼠标右键单击文件时&#xff0c;上下文菜单中还留有“备份到115”的选项&#xff0c;不过…

TNS-12537: TNS:connection closed  TNS-12560: TNS:protocol adapter error   TNS-00507:

TNS-12537: TNS:connection closed TNS-12560: TNS:protocol adapter error TNS-00507: Connection closed Linux Error: 29: Illegal seek 今天启动oracle数据库得lisneter的监听&#xff0c;直接报了上面这几个错误&#xff0c;&#xff0c;于是就开始了排查错误的&…

数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇

HT 是啥&#xff1a;Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向&#xff0c;接着就朝这个方向慢慢打磨&#xff0c;如今 HT 算是达到了这样的效果&#xff0c;谈不上用尽洪荒之力&#xff0c;但我们对产品结果很满意&…
最新文章