Aes 加密 CBC 模式的 Nopadding 填充在 GO 里怎么实现啊

2020-10-09 17:51:58 +08:00
 chengxiao
对接某商户系,被这个签名搞的头大,这个 NoPadding 似乎是个 java 里的方法,没查到相关信息

业务参数加密步骤:
1 )将业务参数转换成 json 格式字符串

2 )用 AES 算法加密,秘钥为 appSecret 重复两遍,偏移量为 appSecret 重复两遍(16 位秘钥不用重复),加密模式 CBC,填充模式; NoPadding

3 )加密后字符即为公共参数 requestBody 的值

业务参数示例:
{
"number":"123",
"string":"测试",
"double":1.0,
"boolean":true
}

开发者秘钥为:12345678

AES 加密结果:
Vq2Kj4Z8C+hFf7VdFPbCoY3LmJgf2LM7B2a3klFxGWMlL1BAxx7v/ZZdkxqdMPXqRPjy3k0tVKgx
KMTTAlbE0PGhp2LtqzouDWZaH1g9ttQ=
2850 次点击
所在节点    Go 编程语言
12 条回复
kingiis
2020-10-09 17:53:39 +08:00
公用 c 库可能会好点
songjiaxin2008
2020-10-09 17:59:49 +08:00
可以参考一下这个实现 https://github.com/wumansgy/goEncrypt 引用的包都是标准库的
songjiaxin2008
2020-10-09 18:00:05 +08:00
NoPadding = ZeroPadding
songjiaxin2008
2020-10-09 18:01:00 +08:00
网页上跑了下应该没啥问题
geelaw
2020-10-09 18:11:33 +08:00
为了数据安全最好还是不要对接这个系统,使用非伪随机的密钥以及使用密钥相关的 IV,都会破坏 AES 所有的安全保证。
teawithlife
2020-10-10 07:42:38 +08:00
其实就是后面补 0x00
play.golang.org/p/MxstiahPDa3
dafsic
2020-10-10 09:49:22 +08:00
我对接过,跟 java 版本有关,问问 java 是什么版本,最好要到加密部分的 java 代码看看
TypeErrorNone
2020-10-10 10:15:17 +08:00
之前写的,可以参考下

```
package xaes

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"github.com/pkg/errors"
)

type Aes struct {
key []byte
}

func NewAes(key string) (*Aes) {
if key == "" {
panic("aes key empty")
}
sum := sha256.Sum256([]byte(key))
return &Aes{
key:sum[:],
}
}

func (a *Aes) Encrypt(encodeBytes []byte) (val string, err error) {
block, err := aes.NewCipher(a.key)
if err != nil {
return
}
blockSize := block.BlockSize()
encodeBytes = a.pkCS5Padding(encodeBytes, blockSize)

iv := make([]byte, blockSize)
_,err = rand.Read(iv)
if err != nil {
return
}

blockMode := cipher.NewCBCEncrypter(block, iv)
crypted := make([]byte, len(encodeBytes))
blockMode.CryptBlocks(crypted, encodeBytes)

iv = append(iv,crypted...)
val = base64.StdEncoding.EncodeToString(iv)
return
}


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

func (a *Aes) Decrypt(decodeStr string) (origData []byte,err error) {
decodeBytes, err := base64.StdEncoding.DecodeString(decodeStr)
if err != nil {
return
}
block, err := aes.NewCipher(a.key)
if err != nil {
return nil, err
}
if len(decodeBytes) < block.BlockSize() {
err = errors.New("decodeBytes 长度不足")
return
}
iv := decodeBytes[:block.BlockSize()]
decodeBytes = decodeBytes[block.BlockSize():]

blockMode := cipher.NewCBCDecrypter(block, iv)
origData = make([]byte, len(decodeBytes))
blockMode.CryptBlocks(origData, decodeBytes)
origData = a.pkCS5UnPadding(origData)
return
}

func (a *Aes) pkCS5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
```
chengxiao
2020-10-10 10:36:16 +08:00
@TypeErrorNone
@teawithlife
@songjiaxin2008
谢谢几位老哥 就是被这个 NoPadding 怎么补位搞蒙了 原来 ZeroPadding 就可以
sunmoon1983
2021-12-02 14:44:05 +08:00
@TypeErrorNone
哥们,我试了试你给的方法,貌似不太行呀,我把 pkCS5Padding 改成了 zeroPadding,最后出来的数据和人家给的数据就是不太一样
sunmoon1983
2021-12-02 14:46:39 +08:00
@chengxiao 哥们,你搞出来了吗? Aes Nopadding 加密
pifuant
268 天前
@sunmoon1983 @chengxiao 老哥们, 怎么解决的,ZeroPadding 不行啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/713404

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX