카테고리 없음

소스코드 보안약점 진단 - 하드코드된 암호화 키

H.J.World 2022. 1. 13. 10:10
728x90
반응형

소스코드 보안약점 진단 // 소프트웨어 보안약점 진단 // SW 보안약점 진단과 같이 다양한 이름으로 불리는 진단 과업 중 하나이다.

SW개발보안은 해킹 등 사이버공격의 원인인 보안약점을 SW개발단계에서 사전에 제거하고 SW 개발 생명주기의 각 단계별로 수행하는 일련의 보안활동을 통하여 안전한 SW를 개발·운영하기 위한 목적으로 적용하는 개발체계이다.

해당 내용은 KISA에서 발간하는 취약점 진단 가이드 항목을 기준으로 작성한다.

 

제2절 보안기능

보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현시 발생할 수 있는 보안 약점으로 적절한 인증 없는 중요기능 허용, 부적절한 인가 등이 포함된다.


10. 하드코드된 암호화 키

가. 개요

코드 내부에 하드코드된 암호화 키를 사용하여 암호화를 수행하면 암호화된 정보가 유출될 가능성이 높아진다. 많은 SW 개발자들이 코드 내부의 고정된 암호키의 해시를 계산하여 저장하면 암호키를 악의적인 공격자로부터 보호할 수 있다고 믿고 있다. 그러나 일부 해시함수들이 역계산이 가능하며, 무차별 대입(Brute-Force) 공격에는 취약하다는 것을 고려해야만 한다.

나. 보안대책

암호화 수행시, 상수가 아닌 암호화 키를 사용하도록 설계해야 한다. 또한, 암호화되었더라도 소스 코드 내부에 상수형태의 암호키를 저장하여 사용해서는 안된다.

다. 코드예제

소스 코드 내부에 암호화 키를 상수 형태로 하드코딩하여 사용하면 악의적인 공격자에게 암호화 키가 노출될 위협이 있다.

- 안전하지 않은 코드의 예 JAVA -

1: import javax.crypto.KeyGenerator;
2: import javax.crypto.spec.SecretKeySpec;
3: import javax.crypto.Cipher;
4: ……
5: public String encriptString(String usr) {
//암호화 키를 소스코드 내부에 사용하는 것은 안전하지 않다.
6: String key = "22df3023sf~2;asn!@#/>as";
7: if (key != null) {
8: byte[] bToEncrypt = usr.getBytes("UTF-8");
9: SecretKeySpec sKeySpec = new SecretKeySpec(key.getBytes(), "AES");

 

- 안전한 코드의 예 JAVA -

암호화 과정에 사용하는 암호화 키는 외부 공간(파일)에 안전한 방식으로 암호화하여 보관해야 하며, 암호화된 암호화 키는 복호화하여 사용한다

1: import javax.crypto.KeyGenerator;
2: import javax.crypto.spec.SecretKeySpec;
3: import javax.crypto.Cipher;
4: ……
5: public String encriptString(String usr) {
//암호화 키는 외부 파일에서 암호화 된 형태로 저장하고, 사용시 복호화 한다.
6: String key = getPassword("./password.ini");
7: key = decrypt(key);
8: if (key != null) {
9: byte[] bToEncrypt = usr.getBytes("UTF-8");
10: SecretKeySpec sKeySpec = new SecretKeySpec(key.getBytes(), "AES");

 

라. 진단방법

DB접속 등 패스워드 사용이 필요한 로직을 확인하고(①), 사용된 패스워드의 암호화 여부 확인한다 (②). 암호화된 패스워드가 소스내에 존재하는지 여부 확인한다(③). 소스코드내에 암호화된 패스워드 를 저장하는 경우 취약하다.

1: …public Connection DBConnect(String url, String usr) {
2: String password = “68af404b513073584c4b6f22b6c63e6b”;--------②
3: try {
4: // 패스워드로 상수를 사용하고있다.
5: con = DriverManager.getConnection(url, usr, password);-------①
6: } catch (SQLException e) {
7: System.err.println(“…”);
8: }
9: return con;
10: }
11: …

 

- 정탐코드의 예 -

암호화를 하는데 사용되는 암호화 키를 소스에 하드코딩해서 사용하는 경우 취약하다.

1: public class U321 {
2: public void foo(String url, String usr) {
3: try {
4: String encryptedPwd = getpassword();
5: // private key를 상수로 정의
6: byte[] privateKey = { ‘6’, ‘8’, ‘a’, ‘f’, ‘4’, ‘0’, ‘4’, ‘b’, ‘5’, ‘1’, ‘3’, ‘0’, ‘7’ };
7: javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(“RSA”);
8: // 상수 key를 사용하여 보안키 생성
9: javax.crypto.SecretKey myDesKey = new javax.crypto.spec.SecretKeySpec(privateKey,
10: “DES”);
11: cipher.init(javax.crypto.Cipher.DECRYPT_MODE, myDesKey);
12: // 암호화된 password를 복호화
13: byte[] plainTextPwdBytes = cipher.doFinal(encryptedPwd.getBytes());
14:
15: // DB 연결
16: java.sql.DriverManager.getConnection(url, usr, new String(plainTextPwdBytes));
17: } catch (SQLException e) {
18: …

 

- 정탐코드의 예 -

암호화를 위한 암호화 키가 아닌 알고리즘명을 지정하는 경우 취약하지 않다.

1: // 키를 설정한다.
2: sKey = new SecretKeySpec( key, “DESede” )

 

728x90
반응형