최근에 C#으로 구현된 프로젝트의 API를 개발하던 중 개발사에서 개발한 암호화 시크릿 키가 8자리로 되어 AES128 방식을 적용한 알고리즘을 건네받았다.
Node.js에서 똑같은 알고리즘과 시크릿 키를 적용하여 아래처럼 구현을 해뒀다
encryptAES128: (text) => {
const aesKey = '12345678';
let cipher = crypto.createCipheriv('aes-128-ecb', aesKey, null,);
let encryptedData = Buffer.concat([cipher.update(text), cipher.final()]);
return encryptedData.toString('base64');
}
그런데 한 가지 문제 점이 발생했는데
aes128 알고리즘의 경우 시크릿키의 길이가 무조건 16바이트 즉 String 16글자를 맞춰야 된다는 것이다.
여기서 한참을 헤매었는데 aesKey 뒤에 공백을 넣을 경우 정상적으로 작동되긴 했지만 공백마저도 문자열로 인식을 하기 때문에 전혀 다른 암호로 생성이 되는 것이다.
그렇다고 8글자를 사용하면 Invalid key length 오류가 뜨게 되는 것이다.
몇 시간을 삽질하던 중
내가 자주 사용하는 암복호화 테스트 사이트인
https://the-x.cn/en-us/cryptography/Aes.aspx
에서 aes128 8글자 시크릿 키로 테스트를 해봤는데 여기선 잘 되던 것이다..
대체 무엇이 다른가 잘 확인해 봤는데 상단에 안내문구로 적혀있던 내용 하나를 발견했다.
`When the user key is not long enough, the tool will be populated with 0x00.`
이 말은 즉 `키의 길이가 충분하지 않을 경우, 해당 툴은 0x00으로 채워집니다`라는 말이다
나는 즉시 node.js에서
12345678의 헥스 코드인 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38를
Buffer.from에 넣어 선언을 했고 그 뒤에 0x00를 8개 더 채워줬다.
아래의 소스코드를 참조하길 바란다.
encryptAES128: (text) => {
const aesKey = Buffer.from([0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
let cipher = crypto.createCipheriv('aes-128-ecb', aesKey, null,);
let encryptedData = Buffer.concat([cipher.update(text), cipher.final()]);
return encryptedData.toString('base64');
}
결과는 성공적이다.
단순히 자릿수만 채워주면 된다고는 생각했는데
근본적인 Hex코드로 공백을 채운다는 생각을 못했었다.
만약 길이가 너무 길어서 오류가 뜬다면, 앞부분 16바이트까지만 자르는 방식을 사용하도록 하면 될 것 같다.
삽질 끝!
'⚙️ Node.js' 카테고리의 다른 글
[Node.js] path 모듈에 대해 알아보자 (0) | 2023.02.20 |
---|---|
[Node.js] Callback 패턴을 async/await 패턴으로 바꾸기 (0) | 2023.02.17 |
[Node.js] MySql 시간 출력 시 Z가 붙는 문제 (0) | 2022.09.02 |
[Node.js] MySql Connection Pool 작동 방식 및 구현 (0) | 2022.07.06 |
[Node.js] MySql PROTOCOL_CONNECTION_LOST 해결 (0) | 2022.07.01 |