记录一次AES复杂解密过程

对AES加密、解密这里不做介绍,不清楚的可以网上查询相关介绍。
这里只记录下AES解密过程,在有限的加密信息下,耗时两天,尝试出来的解密过程。解的怀疑人生。

背景

为了数据的安全性,后端将数据进行了加密,前端需求解密得到正确的JSON。

给到前端的信息

1、AES加密
2、后端加密的一个类文件(java)
3、秘钥KEY

解密过程

解读得到信息:
1、解密模式:ECB (只有一个秘钥KEY值)
2、填充方式:默认Pkcs7
3、后端加密采用了 AES、base64、SHA1、字符串转字节处理

思路:
1、先整理后台的加密规则(看不明白后端代码,只能调试一步,对比结果)
2、按加密的规则进行解密
3、借助第三方解密插件

解密规则

加密内容处理
1.base64 解密 得到字符串
2.字符串转成byte []类型的字节 (注意:字节长度需要/2)
3.将字节转成words对象
4、words对象转 base64的字符串

秘钥key处理
1、字符串转byte []类型的字节(注意:字节长度不需要/2)
2、用sha1加密2次 字节,并转成数组格式
3、截取前16位数组
4、将字节转成words对象(int8parse)

AES解密
模式:EBC
填充方式:PKcs7

数据转字符串
字符串转json对象

实现代码

// 解密方法
const decrypt = (word) => {
  const base64 = decodeURIComponent(escape(window.atob(word)))
  const bytes = onHex(base64)
  console.log('base64', base64)
  console.log('bytes', bytes)
  const keyByte = stringToByte(key)
  console.log('keyByte', keyByte)
  // const bytes = CryptoJS.enc.Utf8.parse(base64)
  const keyByteSha1 = sha1.array(keyByte)
  console.log('keyByteSha1', keyByteSha1)
  const keyByteSha2 = sha1.array(keyByteSha1).slice(0, 16)
  console.log('keyByteSha2', keyByteSha2)
  const keyAes = aesKeyBytes(keyByteSha2)
  console.log('keyAes', keyAes)
  const wordArray = int8parse(bytes)
  console.log('wordArray', wordArray)
  const base64Str = CryptoJS.enc.Base64.stringify(wordArray)
  console.log('base64Str', base64Str)
  const decrypt = CryptoJS.AES.decrypt(base64Str, keyAes, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
  console.log('decrypt', decrypt)
  return JSON.parse(decrypt.toString(CryptoJS.enc.Utf8))
}

// 加解密用到的密钥
function aesKeyBytes(a) {
  const key_Int = new Int8Array(a)
  const keyBytes = int8parse(key_Int)
  return keyBytes
}

// 构建WordArray对象
function int8parse(u8arr) {
  const len = u8arr.length
  const words = []
  for (let i = 0; i < len; i++) {
    words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8)
  }
  return CryptoJS.lib.WordArray.create(words, len)
}

// 字符串转字节 长度需要/2
function onHex(hex) {
  const buffer = new ArrayBuffer((hex.length) / 2)
  const byteStream = new Uint8Array(buffer)
  let i = 0

  while (hex.length >= 2) {
    const x = parseInt(hex.substring(0, 2), 16)

    hex = hex.substring(2, hex.length)

    byteStream[i++] = x
  }
  return byteStream
}

// 字符串转字节 长度不需要/2
export function stringToByte(str) {
  const bytes = []
  let c
  const len = str.length
  for (let i = 0; i < len; i++) {
    c = str.charCodeAt(i)
    if (c >= 0x010000 && c <= 0x10FFFF) {
      bytes.push(((c >> 18) & 0x07) | 0xF0)
      bytes.push(((c >> 12) & 0x3F) | 0x80)
      bytes.push(((c >> 6) & 0x3F) | 0x80)
      bytes.push((c & 0x3F) | 0x80)
    } else if (c >= 0x000800 && c <= 0x00FFFF) {
      bytes.push(((c >> 12) & 0x0F) | 0xE0)
      bytes.push(((c >> 6) & 0x3F) | 0x80)
      bytes.push((c & 0x3F) | 0x80)
    } else if (c >= 0x000080 && c <= 0x0007FF) {
      bytes.push(((c >> 6) & 0x1F) | 0xC0)
      bytes.push((c & 0x3F) | 0x80)
    } else {
      bytes.push(c & 0xFF)
    }
  }
  return bytes
}

依赖:
crypto-js
js-sha1

解密过程结果

base64 
D8061382C771D2525CDAA715BEE1483CB5D19F4003E5352D5495404A0AF9644B2B162184C35FD11B0D254784CEDB3D75B4383AB7BF27321568C2B28DC7D8F3781DF24C021DFCD89053FB6C89990B37C16CD893A3DF38F48AA626944C76F33B970AD4981122306AF636105B5C78A7816480BE93A27541CE1EF048007BA8BCF9E1BC1B2B22DBC84216AF945F5681EE15349EEDE7E8324420BF03C9A002CB6FD3EF6170A5491024861CE7914A7EB31FBC3ED70E81535100D9074EF0951AE98232124600AEC31412D0C4ACD78A19502FE4AFA56FA8C85555DCD5C543F91516C407CB2931E33BF9FE7007764E8C6529C9AFD2D763AC912A4EA3ADBA79738F773DBA2BCB9DF69A6E3124F61110D3D88645DC023F0A030AD53BB8756F498FFA0301B1C65115A9F4FC41F762FA3EDB53DAA91E9075A5F04B2A933EF9422A908105888CCA93F9CE215C31835C76F93AAC0C3BA8539C96CC6B6432662A0FE93D9F2136E483C30CC133C647C505ACFE4D01FEFBA4E634D839EF3302AF91378DFF0D28381D4A186109E754AD6C790C63013159BC5CE7615AF16A0350AA947D1BC42BEC45D66AEC8CE8E2CA7ADA1B7B

bytes 
Uint8Array(432) [216, 6, 19, 130, 199, 113, 210, 82, 92, 218, 167, 21, 190, 225, 72, 60, 181, 209, 159, 64, 3, 229, 53, 45, 84, 149, 64, 74, 10, 249, 100, 75, 43, 22, 33, 132, 195, 95, 209, 27, 13, 37, 71, 132, 206, 219, 61, 117, 180, 56, 58, 183, 191, 39, 50, 21, 104, 194, 178, 141, 199, 216, 243, 120, 29, 242, 76, 2, 29, 252, 216, 144, 83, 251, 108, 137, 153, 11, 55, 193, 108, 216, 147, 163, 223, 56, 244, 138, 166, 38, 148, 76, 118, 243, 59, 151, 10, 212, 152, 17, …]
keyByte 
(36) [102, 49, 48, 97, 48, 97, 52, 49, 45, 55, 55, 99, 54, 45, 52, 98, 97, 54, 45, 52, 51, 50, 51, 45, 101, 51, 102, 98, 50, 48, 53, 97, 97, 99, 102, 97]
keyByteSha1 
(20) [153, 230, 38, 236, 52, 96, 86, 81, 14, 242, 159, 85, 99, 71, 149, 16, 12, 194, 88, 103]
keyByteSha2 
(16) [35, 102, 148, 128, 131, 179, 185, 148, 176, 189, 182, 110, 139, 192, 150, 104]
keyAes 
{$super: {…}, words: Array(4), sigBytes: 16, init: ƒ}

wordArray
{$super: {…}, words: Array(108), sigBytes: 432, init: ƒ}

base64Str 2AYTgsdx0lJc2qcVvuFIPLXRn0AD5TUtVJVASgr5ZEsrFiGEw1/RGw0lR4TO2z11tDg6t78nMhVowrKNx9jzeB3yTAId/NiQU/tsiZkLN8Fs2JOj3zj0iqYmlEx28zuXCtSYESIwavY2EFtceKeBZIC+k6J1Qc4e8EgAe6i8+eG8Gysi28hCFq+UX1aB7hU0nu3n6DJEIL8DyaACy2/T72FwpUkQJIYc55FKfrMfvD7XDoFTUQDZB07wlRrpgjISRgCuwxQS0MSs14oZUC/kr6VvqMhVVdzVxUP5FRbEB8spMeM7+f5wB3ZOjGUpya/S12OskSpOo626eXOPdz26K8ud9ppuMST2ERDT2IZF3AI/CgMK1Tu4dW9Jj/oDAbHGURWp9PxB92L6PttT2qkekHWl8Esqkz75QiqQgQWIjMqT+c4hXDGDXHb5OqwMO6hTnJbMa2QyZioP6T2fITbkg8MMwTPGR8UFrP5NAf77pOY02DnvMwKvkTeN/w0oOB1KGGEJ51StbHkMYwExWbxc52Fa8WoDUKqUfRvEK+xF1mrsj

decrypt 
WordArray.init {words: Array(108), sigBytes: 423}

ossData 
{accessid: 'LT5tK7vA32Gguxu5n6', policy: 'eyJleHBpcmF0aW9o0MzoxOC4yNT…wMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJjc20vIl1dfQ==', signature: 'sd2p/uQtVe1maCPkr4BxF9TU=', …}

后续在记录一篇前后端项目统一加解密的处理流程,封装SDK,对外只提供接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值