flutter 학습을 위해 기록함.
안드로이드 앱에서 restful API를 연동하여 데이터 값을 처리하기 위해 필요한 AES-256 암호화 및 복호화 코드
1) flutter 패키지 encrypt 설치
pub global activate encrypt
2) 코드 작성
import 'package:encrypt/encrypt.dart' as encrypt;
class MyCrypt {
// 암호화
static String AES_encrypt(String normalData) {
final key = encrypt.Key.fromUtf8('암호화키로 사용될 32byte 길이의 문자열');
final iv = encrypt.IV.fromUtf8('IV값으로 사용될 16byte 길이의 문자열');
final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
final encrypted = encrypter.encrypt(normalData, iv: iv);
return encrypted.base64;
}
// 복호화
static String AES_decrypt(String encryptedData) {
final key = encrypt.Key.fromUtf8('암호화키로 사용될 32byte 길이의 문자열');
final iv = encrypt.IV.fromUtf8('IV값으로 사용될 16byte 길이의 문자열');
final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
final decrypted = encrypter.decrypt(encrypt.Encrypted.from64(encryptedData), iv: iv);
return decrypted;
}
}
// 사용
var encodeData = MyCrypt.AES_encrypt('암호화할 문자열');
var decodeData = MyCrypt.AES_decrypt(encodeData); // 암호화된 문자열
3) 팁
iv값의 길이는 암호화키보다 짧으므로, 암호화키 문자열에서 추출하여 사용하는 것도 가능함.
단, 암/복호화에 사용되는 key와 iv값은 동일해야 정상적인 복호화가 됨.
var keyString = '32byte길이의 암호화키 문자열';
final key = encrypt.Key.fromUtf8(keyString);
final iv = encrypt.IV.fromUtf8(keyString.toLowerCase().substring(0, 16));
참조
[공식] https://pub.dev/packages/encrypt
https://link2me.tistory.com/2215
4) 오류 및 디버깅
Invalid or corrupted pad block using encrypt package
sol.> 암호화키 문자열의 길이에 따라 AES 암호화 방식이 구분됨.
16byte -> AES-128, 24byte -> AES-192, 32byte -> AES-256
키 문자열 길이가 16, 24, 32byte 이중에 하나도 아니면, 에러가 발생함.
* 참조 https://kkh0977.tistory.com/6307
flutter/runtime/dart_vm_initializer.cc(41)] unhandled exception: invalid argument(s): input buffer too short
sol> 서버와 연동을 하려다보니 복호화부터 진행해야 했고, 다시 암호화하려니 위와 같은 에러가 발생함. 이에 대한 원인은 키값의 길이가 맞지 않아서 라고 이미 stackoverflow에서 언급되고 있음.
( https://stackoverflow.com/questions/70817666/invalid-arguments-input-buffer-too-short-and-invalid-or-corrupted-pad-block)
그런데 암호화 키값, iv값 길이 모두 확인해봐도 이상이 없음.
결국 찾아낸 원인은 암호화 처리 할때, padding 옵션과 평문의 길이가 매칭되지 않아서 오류가 발생되었음.
final encrypter = encrypt.Encrypter(encrypt.AES(
encrypt.Key.fromUtf8(encryptKey),
mode: encrypt.AESMode.cbc,
padding: null,
)); // 오류가 발생된 코드
padding: null은 평문의 길이가 16바이트의 배수가 아니면 encrypt 메서드에서 오류가 발생할 수 있다고 함. 해결책은 제거하거나 옵션을 Pkcs7Padding()를 사용하면 됨. 난 제거 했음.
'IT 개발' 카테고리의 다른 글
[flutter] 앱 시작화면. 스플래시(splash) 적용하기 (1) | 2025.02.17 |
---|---|
[flutter] 안드로이드 앱 APK 추출 (0) | 2025.02.14 |
[PHP] Composer 에러. mikey179/vfsStream (0) | 2021.06.11 |
[파이썬] CentOS 리눅스 selenium 오류 - ChromeDriver 문제 해결 (0) | 2020.11.22 |
[git] 대용량 파일 저장 git-lfs (Git Large File Storage) (0) | 2020.11.18 |