728x90

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()를 사용하면 됨. 난 제거 했음.

반응형

+ Recent posts