암호화 통신 모듈에 대한 C# 용 클라이언트 라이브러리 개발 - Whitmem
암호화 통신 모듈에 대한 C# 용 클라이언트 라이브러리 개발
Develop History
2023-05-19 09:31 게시 8c95a14a1c60dbea6f0f

0
0
285
이 페이지는 외부 공간에 무단 복제할 수 없으며 오직 있는 그대로 게시되며 부정확한 내용을 포함할 수 있습니다. 법률이 허용하는 한 가이드 라인에 맞춰 게시 내용을 인용하거나 출처로 표기할 수 있습니다.
This page is not to be distributed to external services; it is provided as is and may contain inaccuracies.
암호화 통신 C#용 라이브러리 개발
이전에 필자는 자바 기반에서 동작되는 암호화 통신 라이브러리를 개발하였습니다. 자바끼리 통신은 잘 되지만, 실제 자바에서 서버를 구축하고 클라이언트로 C# 등을 사용하는 경우가 제법 많았습니다. 필요에 따라서 C#에서도 암호화 서버에 접속해야 할 상황이 생기게 되었고, 실행에 옮겼습니다.
문제
하지만, 문제가 하나 존재했는데 바로 언어가 다르다는 점 입니다. 물론 자바 기반의 라이브러리를 별도 도구를 사용해 C#과 함께 자바 런타임 내에서 돌아가도록 작성해주는 도구가 있는 것 같지만 런타임에 의존한다는 문제가 존재할 것 같았습니다. 따라서 직접 C#에서도 구현을 하기로 결정합니다.
개발
기본적으로 자바 소스코드 형태와 C#의 소스코드 형태는 유사하므로 클래스 관계 역시 유사하게 구성했습니다.
위와 같은 클래스 구성이 존재했다면, C#에서는 다음과 같이 클래스를 구성하였습니다.
다만 내부 built-in 메소드 및 클래스는 확실하게 다르기 때문에 별도 메모리를 관리하거나 처리하는 부분은 모두 수정해 주었습니다.
예를 들어, Java에서 메모리 스트림을 관리하기 위해 ByteArrayInputStream을 사용하면 되지만 C#에서는 ByteArrayInputStream이 존재하지 않기 때문에, MemoryStream으로 처리를 진행하도록 포팅합니다.
Java 내 메모리 스트림 관리
C# 내 메모리 스트림 관리
또한, C#에서의 바이트 처리 방법과 Java에서의 바이트 처리 방법이 사소하게 다른 부분, 엔디안 처리가 다른 부분을 고려해 다시 역으로 뒤집는 작업등을 진행 해 주었습니다.
AES 암호화 부분도 간단하지는 않았습니다. 자바에서는 GCMParameterSpec로 처리하는 경우 ChipherText 뒤에 자동으로 태그가 붙지만, C#에서는 그러지 않았습니다. 따라서 직접 붙이고 관리해주는 메소드를 구현하였습니다.
제일 크게 골치 아픈 부분이었습니다. 안전한 암호 통신을 위해서는 RSA 암호화/복호화 작업을 진행해야 하는데, C#에서 암호화한 자료를 자바에서 복호화하기 위해서는 키의 규격이 동일해야 합니다. 즉 자바에서는 이러한 구조로 만들어진 공개키 bytes를 C#에 무조건 집어넣으면 잘못된 암호화를 진행할 수 있습니다.
특히 본인은 자바에서 X509EncodedKeySpec을 통해 공개키를 처리하는데, C#에서의 X509Certification으로는 처리가 되지 않았습니다. 찾아보니 나열 방식이 다르고 이 클래스에서는 해당 X509 방식 이전에 나열 방식이 지원되지 않는다고 들었고, 별도의 라이브러리를 사용해야 하거나 Modulus 또는 Exponents 를 추출하는 메소드를 사용해야 한다고 했습니다. 많은 고민 끝에, 자바에서 바로 Modulus 와 Exponents 를 추출해주는 메소드가 built-in으로 있었고, 해당 부분을 활용하여 직접 Array를 구성한 뒤 Base64Encoded 로 String화 하여, C#에 전송, 처리하도록 구현했습니다. 결과적으로 자바 기반에서 동작되는 라이브러리와 C#에서 동작되는 라이브러리가 받는 공개키 규격이 다르게끔 구현하였습니다. 다만, 공개키 규격이 다를 뿐, 같은 암호 정보를 가르킵니다.
테스트
먼저 서버를 열어봅니다.

여기서 C# 라이브러리에서 사용하기 위해 직접 구성한 공개키를 클라이언트 라이브러리에 기입합니다.
연결 후 암호화 채팅을 진행 해 봅니다.
여러 클라이언트를 실행하여 테스트해봅니다.
C# 기반의 클라이언트뿐만이 아니라, 자바 기반의 클라이언트에서도 접속을 해봅니다.
서버는 접속하는 클라이언트 버전에 따라서 알맞는 규격의 공개키를 보냅니다.
C# 기반의 클라이언트에서 분류한 모습
Java 기반의 클라이언트에서 분류한 모습
자바 기반의 클라이언트에서 메시지를 보내면 C# 기반의 클라이언트에서 정상적으로 메시지를 받고 보낼 수 있습니다.
작업시간
C# 클라이언트에서 동작되도록 개발하는데 약 8시간 걸린 것 같습니다. 처음으로 RSA 와 AES를 다른 플랫폼간 통신을하고 동작되게 하는지라 삽질을 약 4-5시간 한 것 같습니다. 구현 자체는 오래 걸리지 않았네요.
댓글 0개
댓글은 일회용 패스워드가 발급되며 사이트 이용 약관에 동의로 간주됩니다.
확인
Whitmemit 개인 일지 블로그는 개인이 운영하는 정보 공유 공간으로 사용자의 민감한 개인 정보를 직접 요구하거나 요청하지 않습니다. 기본적인 사이트 방문시 처리되는 처리 정보에 대해서는 '사이트 처리 방침'을 참고하십시오. 추가적인 기능의 제공을 위하여 쿠키 정보를 사용하고 있습니다. Whitmemit 에서 처리하는 정보는 식별 용도로 사용되며 기타 글꼴 및 폰트 라이브러리에서 쿠키 정보를 사용할 수 있습니다.
이 자료는 모두 필수 자료로 간주되며, 사이트 이용을 하거나, 탐색하는 경우 동의로 간주합니다.