DynamicLinks 암호화 / 복호화
필자의 경우 JAVA 에서 암호화 된 값을 dart에서 복호화해 api 통신을 통한 자동 로그인을 구현했습니다
flutter 3.7.12 기준
AES/CBC/PKCS5Padding 기준 암호화
aes cbc 방식이란?
암호 블록 체인 (cipher-block chaining, CBC) 방식은 1976년 IBM에 의해 개발되었다. 각 블록은 암호화되기 전에 이전 블록의 암호화 결과와 XOR되며, 첫 블록의 경우에는 초기화 벡터가 사용된다. 초기화 벡터가 같은 경우 출력 결과가 항상 같기 때문에, 매 암호화마다 다른 초기화 벡터를 사용해야 한다.
CBC 방식은 현재 널리 사용되는 운용 방식 중 하나이다. CBC는 암호화 입력 값이 이전 결과에 의존하기 때문에 병렬화가 불가능하지만, 복호화의 경우 각 블록을 복호화한 다음 이전 암호화 블록과 XOR하여 복구할 수 있기 때문에 병렬화가 가능하다.
encrypt: ^5.0.1 라이브러리 사용 복호화
https://pub.dev/packages/encrypt
encrypt | Dart Package
A set of high-level APIs over PointyCastle for two-way cryptography.
pub.dev
Encrypter
static final byte[] iv = new byte[16];
String value = AESUtils.encryptBase64("암호키 값", "test");
public static String encryptBase64(String secret, String data) {
try {
return Base64.encodeBase64String(encrypt(secret, data));
} catch (EncryptionException e) {
e.printStackTrace();
return "";
}
}
public static byte[] encrypt(String secret, String data) throws EncryptionException {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes("UTF-8"), "AES");
AlgorithmParameterSpec ivParam = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParam);
return cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
} catch (NoSuchAlgorithmException
| NoSuchPaddingException
| InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException
| UnsupportedEncodingException e) {
e.printStackTrace();
throw new EncryptionException(e);
}
}
암호화 된 값을 다이나믹링크 파라미터에 담아 요청
앱이 실행되며 flutter firebase 이벤트 리스너 수신
Decrypted
FirebaseDynamicLinks.instance.onLink.listen(
(pendingDynamicLinkData) async {
Uri link = pendingDynamicLinkData.link;
String? key= link.queryParameters['key'];
final encryptKey = encrypt.Key.fromUtf8('암호키 값'); // 암호화 할때 설정한 키
final iv = encrypt.IV.fromLength(16);
final encrypter =
encrypt.Encrypter(encrypt.AES(encryptKey, mode: encrypt.AESMode.cbc));
final decrypted = encrypter.decrypt64(key!, iv: iv);
print(decrypted);
// 복호화 된 값 출력
}
);
작성자의 경우 똑같은 요청을 또 다시하면 N번씩 이벤트리스너가 잡아 같은 페이지를 여러번 호출하기 되었다
이로인해 GlobalKey 중복 오류가 발생해
아래와 같이 임시 처리로 조치 했다
bool flag = true;
이벤트 수신시 flag 값 이용해 false 가 되면 다시 실행하지 못하도록 처리 함
FirebaseDynamicLinks.instance.onLink.listen(
(pendingDynamicLinkData) async {
Uri link = pendingDynamicLinkData.link;
if (flag) {
flag = false;
/*암호화된 파라미터 값 이용 로그인 처리*/
dynamicLinkLogin(link);
}
},
);
느낀점 : 암호화 알고리즘을 좀더 찾아보고 공부하고 사용해 봐야 겠다