热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

golang中几种加密方式的处理

缘由在与第三方平台进行接入的时候,通常会存在一些签名或者加密的处理,在进行开发的时候,因为语言的不同,需要按照规范进行相应处理。DES加解密DES:https:en.wikiped

缘由

在与第三方平台进行接入的时候,通常会存在一些签名或者加密的处理,在进行开发的时候,因为语言的
不同,需要按照规范进行相应处理。

DES加解密

DES:https://en.wikipedia.org/wiki/Data_Encryption_Standard

golang中的标准库crypto/des中有DES的实现,但是golang库的描述比较简单,如果不熟悉DES的加密规则,是不容易
进行相应代码编写的,与第三方进行不同语言之间的加密与解密时,也容易混淆,出现错误。

DES区分为CBC和EBC加密模式,并且有不同的填充方式。

CBC(等):https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
Padding:https://en.wikipedia.org/wiki/Padding_(cryptography)

注意 PKCS#5 padding is identical to PKCS#7 padding

所以对不同的平台与语言进行DES加解密对接时,需要知道对方的是采用何种加密模式以及何种填充方式:

  • Windows 默认是CBC模式,CryptSetKeyParam函数,openssl 函数名中直接表明

  • Java 中如果Cipher.getInstance()中不填写,默认是DES/ECB/PKCS5Padding

  • C# 中默认是CBC模式,PKCS7Padding(PKCS5Padding)

golang默认提供的是CBC模式,所以对于ECB模式,需要自己编写代码

PKCS5Padding与PKCS5Unpadding

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)]
}

ECB加密模式


block, err := des.NewCipher(key)
if err != nil {
...
}
bs := block.BlockSize()
src = PKCS5Padding(src, bs)
if len(src)%bs != 0 {
....
}
out := make([]byte, len(src))
dst := out
for len(src) > 0 {
block.Encrypt(dst, src[:bs])
src = src[bs:]
dst = dst[bs:]
}
...
}

ECB下的解密


block, err := des.NewCipher(key)
if err != nil {
...
}
out := make([]byte, len(src))
dst := out
bs := block.BlockSize()
if len(src)%bs != 0 {
...
}
for len(src) > 0 {
block.Decrypt(dst, src[:bs])
src = src[bs:]
dst = dst[bs:]
}
out = PKCS5UnPadding(out)

RSA加解密

与其他语言默认有更高级的封装不同,golang中需要依据不同的概念,自己组合进行封装处理,为此,需要先理解几个不同的概念。

PEM: https://en.wikipedia.org/wiki/Privacy-enhanced_Electronic_Mail,通常是以.pem结尾的文件,在密钥存储和X.509证书体系中使用比较多,下面是一个X509证书下的PEM格式:

-----BEGIN CERTIFICATE-----
base64
-----END CERTIFICATE-----

PKCS:https://en.wikipedia.org/wiki/PKCS,这是一个庞大的体系,不同的密钥采用不同的pkcs文件格式。如私钥采用pkcs8。

X.509:https://en.wikipedia.org/wiki/X.509,这是一个公钥管理基础(public key infrastructure, pki),在IETF中通常对应PKIX。

说明:

使用 openssl(如openssl genrsa -out rsa_private_key.pem 1024)生成的pem文件,就是符合PEM格式的,以-----BEGIN RSA PRIVATE KEY-----开头,-----END RSA PRIVATE KEY-----结尾。

也可以转换为pkcs8:

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

注意,虽然数据格式pkcs8格式,但是-outform也表明了,文件格式仍旧是符合PEM格式的,只是两个PEM文件是存在差异的。

清楚了上面几种概念与格式之后,编写golang对应的公钥与私钥加解密方式,就相对容易一些,首先是将pem文件解码,然后进行对应的密码解码为golang支持的结构体,再进行相应的处理。

如对于私钥,可以进行如下操作进行签名:

block, _ := pem.Decode([]byte(key))
if block == nil { // 失败情况
....
}
private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
...
}
h := crypto.Hash.New(crypto.SHA1)
h.Write(data)
hashed := h.Sum(nil)
// 进行rsa加密签名
signedData, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), crypto.SHA1, hashed)
...

通过私钥进行解密,代码格式如下;


block, _ := pem.Decode([]byte(key))
if block == nil { // 失败情况
....
}
private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
...
}
v, err := rsa.DecryptPKCS1v15(rand.Reader, private, data)
...

对于公钥对数据进行加密:


block, _ := pem.Decode([]byte(key))
if block == nil { // 失败情况
....
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
...
}
encryptedData, err := rsa.EncryptPKCS1v15(rand.Reader, pub.(*rsa.PublicKey), data)
...

小结

搞清楚具体的加密方式,然后再在golang里面编写,代码还是很清晰也不难看懂。

文章发布于 https://segmentfault.com/a/1190000004151272,作者:Damon


推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
author-avatar
手机用户2602933853
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有