项目场景:
今天蛮沮丧的,在和别人对接的时候aes加解密的时候踩了坑。今天有个同事请假了,所以本来他和别人对接的活,老大给了我,然后我就正式踏上了战战兢兢的对接之路。
1.一开始的时候对面先是问用的啥加密方法。这个我记得当时做的时候我就在旁边还问我了的,AES。顺利答出。
2.然后对面又问要key和偏移量,key我知道,偏移量是什么鬼,然后去百度了一下,一个叫IV的东西,对加密有点了解脑子里大概知道是做啥用的了,去找了一下还真有,key,iv都发过去了。还算顺利
问题描述
到这里应该都结束了。哪曾想对面拿到这两个东西,解密还是解不了,解密返回的是空。
原因分析:
然后我就开始找原因
①我先是试了一下我本地加密解密,ok没有问题
②我又试了一下在密文前面加空格然后解密,返回的是空,那是不是就是这个原因呢,发给对面让对面把空格去了试试,好还是不行
③然后就是半个多小时过去,对面看我久久不回,把解密的方法发给了我,我看了一下和我这边差别不大,唯一有差别的就是
对面的key是我发的字符串
,而我这边的key是生成的
有没有可能是两个不一样呢,我把两个都输出比较了一下都一样的没问题看起来都是字符串。这是我踩的第一个坑。
然后呢,不信自己的眼睛又用了一下key == key1 输出了一下true,也没问题呀。这是我踩的第二个坑。被两个坑给埋了。
最后问同事,同事试了一下也愣住了,然后我给他展示了一下我用key == key1是true ,他让我试试 key === key1,一输出false,好这个时候原因很明显了,我又用typeof key,输出了是object,好家伙。
至于key == key1为什么是true,我想大概是对象的toString方法,让他输出了和key1相等的字符串
解决方案:
最后最后我把对面晾了两个多小时,对面让我把生成密钥的盐值,密码短语,KEY_SIZE,ITERATION_COUNT都发给他,自己生成密钥去了。
虽然问题解决了,但是还是要探讨一下有密钥了,这个key到底应该怎么写。我的chat今天下午竟然罢工了,不然问一下应该很快就能解决(顺便吐槽一下国内的大模型真lj,根本比不了),目前还用不了,先记录一下,等能用了我再问问。
回来填坑
直接这么写不行
然后这样写
var key2 = CryptoJS.enc.Utf8.parse("asdfasdfsadfsadfasdf");
输出了一下
用这个key2解密还是不行,一样返回为空
突发奇想又把正确的key输出了一下
哦,很明显问题出来了,比正确的key长,问问chat老师
User
还是key不对,var key =
CryptoJS.enc.Utf8.parse(“222d95e87666d9eed4429e0a2daa39a8”);
生成的key,array是8,正确应该是5?
在你提到的情况下,密钥的生成可能存在问题。AES 的密钥长度应该是 128 位(16 字节),192 位(24 字节)或 256 位(32
字节)。你提到生成的密钥数组长度为 8,这不符合标准的 AES 密钥长度。如果你的密钥是 32 位的十六进制字符串,你可以使用 CryptoJS.enc.Hex.parse
来解析为字节数组。确保使用正确的密钥长度,可以根据需要截断或补齐。例如:javascript Copy code // 如果密钥是 32 字节的十六进制字符串 var keyHex =
“222d95e87666d9eed4429e0a2daa39a8”; var key =
CryptoJS.enc.Hex.parse(keyHex); 上述代码将 32
字节的十六进制字符串解析为字节数组,然后你可以将其用作密钥。确保你的密钥长度正确,并尽量不要硬编码密钥,因为密钥的保密性非常重要。最好的做法是将密钥存储在安全的地方,而不是在代码中硬编码。如果你需要使用密码来派生密钥,可以考虑使用密码学上的密钥派生函数(如
PBKDF2)。
User
和CryptoJS.enc.Utf8.parse(“222d95e87666d9eed4429e0a2daa39a8”);有什么区别
在 CryptoJS 中,CryptoJS.enc.Utf8.parse 和 CryptoJS.enc.Hex.parse
是两个不同的方法,用于解析字符串并生成对应的字节数组。CryptoJS.enc.Utf8.parse:
该方法将 UTF-8 编码的字符串转换为字节数组。 适用于包含文本字符的字符串。
例如:CryptoJS.enc.Utf8.parse(“Hello, World!”) 会生成一个包含每个字符的 UTF-8
编码的字节数组。 CryptoJS.enc.Hex.parse:该方法将十六进制字符串转换为字节数组。 适用于包含十六进制字符的字符串,每两个字符表示一个字节。
例如:CryptoJS.enc.Hex.parse(“48656c6c6f2c20576f726c6421”) 会生成一个字节数组,对应于
ASCII 编码的 “Hello, World!”。 在你的情况下,你提到密钥是一个 32 位的十六进制字符串:javascript Copy code var key =
CryptoJS.enc.Hex.parse(“222d95e87666d9eed4429e0a2daa39a8”); 这里使用了
CryptoJS.enc.Hex.parse,因为你提供的密钥是一个十六进制字符串。这样可以确保正确地将这个字符串转换为字节数组,以便在
CryptoJS 的 AES 加密和解密过程中使用。如果密钥是一个普通的文本字符串,而不是十六进制,你应该使用 CryptoJS.enc.Utf8.parse。
总的来说,选择使用哪个方法取决于你的密钥的表示形式。如果密钥是十六进制字符串,使用
CryptoJS.enc.Hex.parse;如果是普通文本字符串,使用
CryptoJS.enc.Utf8.parse。在加密和解密的过程中,确保使用相同的格式来处理密钥。
总结一下喽如果想要把key直接写出来得把密钥写成十六进制的字符串
var key = CryptoJS.enc.Hex.parse("asdfasdfsadfsadfasdf");