Microsoft MVP성태의 닷넷 이야기
.NET Framework: 292. RSACryptoServiceProvider의 공개키와 개인키 구분 [링크 복사], [링크+제목 복사],
조회: 39082
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

(시리즈 글이 14개 있습니다.)
.NET Framework: 292. RSACryptoServiceProvider의 공개키와 개인키 구분
; https://www.sysnet.pe.kr/2/0/1218

.NET Framework: 327. RSAParameters와 System.Numerics.BigInteger 이야기
; https://www.sysnet.pe.kr/2/0/1295

.NET Framework: 329. C# - Rabin-Miller 소수 생성방법을 이용하여 RSACryptoServiceProvider의 개인키를 직접 채워보자
; https://www.sysnet.pe.kr/2/0/1300

.NET Framework: 356. (공개키를 담은) 자바의 key 파일을 닷넷의 RSACryptoServiceProvider에서 사용하는 방법
; https://www.sysnet.pe.kr/2/0/1401

.NET Framework: 383. RSAParameters의 ToXmlString과 ExportParameters의 결과 비교
; https://www.sysnet.pe.kr/2/0/1491

.NET Framework: 565. C# - Rabin-Miller 소수 생성 방법을 이용하여 RSACryptoServiceProvider의 개인키를 직접 채워보자 - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/10925

.NET Framework: 566. openssl의 PKCS#1 PEM 개인키 파일을 .NET RSACryptoServiceProvider에서 사용하는 방법
; https://www.sysnet.pe.kr/2/0/10926

.NET Framework: 638. RSAParameters와 RSA
; https://www.sysnet.pe.kr/2/0/11140

.NET Framework: 1037. openssl의 PEM 개인키 파일을 .NET RSACryptoServiceProvider에서 사용하는 방법 (2)
; https://www.sysnet.pe.kr/2/0/12598

.NET Framework: 2093. C# - PKCS#8 PEM 파일을 이용한 RSA 개인키/공개키 설정 방법
; https://www.sysnet.pe.kr/2/0/13245

닷넷: 2297. C# - ssh-keygen으로 생성한 Public Key 파일 해석과 fingerprint 값(md5, sha256) 생성
; https://www.sysnet.pe.kr/2/0/13739

닷넷: 2297. C# - ssh-keygen으로 생성한 ecdsa 유형의 Public Key 파일 해석
; https://www.sysnet.pe.kr/2/0/13742

닷넷: 2300. C# - OpenSSH의 공개키 파일에 대한 "BEGIN OPENSSH PUBLIC KEY" / "END OPENSSH PUBLIC KEY" PEM 포맷
; https://www.sysnet.pe.kr/2/0/13747

닷넷: 2302. C# - ssh-keygen으로 생성한 Private Key와 Public Key 연동
; https://www.sysnet.pe.kr/2/0/13749




RSACryptoServiceProvider의 공개키와 개인키 구분

데브피아 질문이 있군요.

RSA 암호화에 대해 질문드립니다.  
; http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=17&MAEULNO=8&no=142654&ref=142654&page=1

질문의 요지는, RSAParameters에서 공개키와 개인키를 구분해서 저장하는 방법이라고 볼 수 있습니다.

우선, RSA에서 암호화를 하기 위해서는 '공개키'를 사용한다는 것과 복호화를 하기 위해서는 '개인키'를 사용한다는 개념은 알고 계셔야 겠지요.

이를 바탕으로, 여러분이 RSA 암호화를 구현하고 싶다면 우선 (공개키를 포함한) 개인키를 생성해야 합니다. 이는 다음과 같이 간단하게 할 수 있습니다.

RSAParameters privateKey = RSA.Create().ExportParameters(true);

만약, ExportParameters에 false를 주면 공개키만을 반환해 주므로 의미가 없습니다. 자, 그럼 이렇게 반환된 개인키로부터 공개키는 어떻게 가져올 수 있을까요? 간단합니다. ^^ 다음과 같이 개인키로부터 Modulus와 Exponent 값만 취해서 별도의 RSAParameters 타입으로 구성해 주면 됩니다.

RSAParameters publicKey = new RSAParameters();
publicKey.Modulus = privateKey.Modulus;
publicKey.Exponent = privateKey.Exponent;

공개키는 말 그대로 공개해서 사용할 수 있도록 해주면 되는데 다음과 같이 XML 문자열로 변환해서 배포할 수 있습니다.

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(publicKey);
string publicKeyText = rsa.ToXmlString(false);

publicKeyText 값:

<RSAKeyValue><Modulus>3GujGHHw7hecMfuyU9W1mkAA1FqOolhSaKl8jF4wuJW26rwr7P/QjljwD
+Tyav2DVDJ0tW93VgzZV3rjMq2FDpjyEUOOMfiGptSeYtQica+6rLb5g+n0ZYh8lI7VGwiy4/OTAHc/
OBBmb8VNvG6yKwxeRcX2v5mrkjHjQcXMoc8=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

개인키도 마찬가지 방식으로 XML 문자열로 저장할 수 있습니다.

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(privateKey);
string privateKeyText = rsa.ToXmlString(true);

privateKeyText 값:

<RSAKeyValue><Modulus>3GujGHHw7hecMfuyU9W1mkAA1FqOolhSaKl8jF4wuJW26rwr7P/QjljwD
+Tyav2DVDJ0tW93VgzZV3rjMq2FDpjyEUOOMfiGptSeYtQica+6rLb5g+n0ZYh8lI7VGwiy4/OTAHc/
OBBmb8VNvG6yKwxeRcX2v5mrkjHjQcXMoc8=</Modulus><Exponent>AQAB</Exponent><P>+BTv/
DqzhEecQqJ7PT4bWQWDzCpr6/itZtyaN1cqi9V+c5wmDKc/szB2mGTVeUJ5NuPIixtwcL4yoeQr26aV1w==</
P><Q>43SuMl9XyVjXw/Vvvgq5s3LR0oVzQpw5YcaWHgHWCwIF6+kTdtwsgaL4e3QjCq9dxPPJm0DkwAIndRGwvS9kyQ==</
Q><DP>Jyy/PNhUMsZQIaGgzmn5TZR2XI4yXp/1WfHqFGUaXdyHzF/TDlp2z6gOgkAiCbT6iTVtHLJnjhYqzq/GUTg8Hw==</
DP><DQ>1bjxZYuI5TyBoTOhx6Q0UZV16qZSYyiAEouSyqdXBAjmn4DmNS009Kq5aOb7djLJnSKlMSiMyI49nRb+RwWdYQ==</
DQ><InverseQ>HIWjouZtBwUJqg6VCxrXQBvpd+3OdLqx8ScGR1tpGVxT9MijkVlmXbkEe7cYFZlw7iToEBfQrcmy6AWEpXl1NA==</
InverseQ><D>vAZxpSulK2Umj5i2oT8fYAqS6pKpM6GGAtP5c7/xbbQAyjJkghIidRs3BUf25v
+E5PD5j8AbG2Nwj2g7oQJWCe0UyX6pWsbUAaiv6dIop664q5UDVSulJXlAV3eV/vT6/ohMTFej7h1LQ/8crPd2wv8p+NYAIh+H719A/NqjOTE=</
D></RSAKeyValue>

물론, 개인키를 Import 한 다음에 ToXmlString에서 false 인자를 주면 공개키만 export 하게 됩니다.

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(privateKey);
string publicKeyText = rsa.ToXmlString(false);

자... 이렇게 해서 공개키 문자열을 보관하고 있는 측에서는 XML 문자열로부터 공개키를 다시 Import 할 수 있고 암호화를 해주면 됩니다.

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(publicKeyText);
rsa.Encrypt(...DataToEncrypt..., false);

개인키에 대한 XML을 보관하고 있는 측에서도 역시 개인키를 동일하게 Import하고 복호화 해 줄 수 있습니다.

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privateKeyText);
rsa.Decrypt(...DataToDecrypt..., false);

설명이 끝난 것 같군요.

첨부된 파일은 위의 코드를 포함한 예제 프로젝트입니다.

참고로, 이 내용은 모두 다음의 MSDN 문서에 있는 것입니다. ^^

RSACryptoServiceProvider 클래스
; https://docs.microsoft.com/ko-kr/dotnet/api/system.security.cryptography.rsacryptoserviceprovider




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 8/12/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2013-08-06 10시09분
Javascript와 .NET 간의 RSA 암호화 데이터 교환 방법을 구현한 코드 예제가 있군요. ^^

로그인 RSA 암호화 asp.net
; http://blog.naver.com/103hana/10166459171

저도 언제 한번 이와 관련해서 글을 쓰려고 했는데 ^^ 그럴 필요가 없어졌군요. 참고로, 위의 글에 나온 js 소스 코드는 다음의 경로에서 구할 수 있습니다.

RSA and ECC in JavaScript
; http://www-cs-students.stanford.edu/~tjw/jsbn/

URL 경로로 판단해 보건데... 아무래도 오래 지속될 것 같진 않으므로 위의 페이지 자체를 mhtml로 변환해서 소스 코드와 함께 이 글에 첨부해 두었으니 참고하세요. ^^
정성태

... [121]  122  123  124  125  126  127  128  129  130  131  132  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
10899정성태2/17/201623342개발 환경 구성: 282. kernel32.dll, kernel32legacy.dll, api-ms-win-core-sysinfo-l1-2-0.dll [1]
10898정성태2/17/201621798.NET Framework: 547. PerformanceCounter의 InstanceName 지정 시 주의 사항파일 다운로드1
10897정성태2/17/201621138디버깅 기술: 76. windbg 분석 사례 - 닷넷 프로파일러의 GC 콜백 부하
10896정성태2/17/201622305오류 유형: 320. FATAL: 28000: no pg_hba.conf entry for host "fe80::1970:8120:695:a41e%12"
10895정성태2/17/201621102.NET Framework: 546. System.AppDomain으로부터 .NET Profiler의 AppDomainID 구하는 방법 [1]
10894정성태2/17/201621828오류 유형: 319. Visual Studio에서 찾기는 성공하지만 해당 소스 코드 정보가 보이지 않는 경우
10893정성태2/16/201620475.NET Framework: 545. 닷넷 - 특정 클래스가 로드되었는지 여부를 알 수 있을까? - 두 번째 이야기
10892정성태2/16/201621093오류 유형: 318. 탐색기에서 폴더 생성/삭제 시 몇 초 동안 멈추는 현상
10891정성태2/16/201624113VC++: 95. 내 CPU가 MPX/SGX를 지원할까요? [1]
10890정성태2/15/201623984.NET Framework: 544. C# 5의 Caller Info를 .NET 4.5 미만의 응용 프로그램에 적용하는 방법 [5]
10889정성태2/14/201620269.NET Framework: 543. C++의 inline asm 사용을 .NET으로 포팅하는 방법 - 두 번째 이야기파일 다운로드1
10888정성태2/14/201618625.NET Framework: 542. 닷넷 - 특정 클래스가 로드되었는지 여부를 알 수 있을까?
10887정성태2/3/201619289VC++: 94. MPX(Memory Protection Extensions) 테스트파일 다운로드1
10886정성태2/3/201620525개발 환경 구성: 281. Intel MPX Runtime Driver 수동 설치
10885정성태2/2/201620214오류 유형: 317. Sybase.Data.AseClient.AseException: The command has timed out.
10884정성태1/11/201621433개발 환경 구성: 280. 닷넷에서 SAP Adaptive Server Enterprise 데이터베이스 사용파일 다운로드1
10882정성태1/6/201620728Windows: 113. 윈도우의 2179, 26143, 47001 TCP 포트 사용 [1]
10881정성태1/3/201622165오류 유형: 316. 윈도우 10 - 바탕/돋음 체가 사라져 한글이 깨지는 현상 [2]
10880정성태12/16/201519838오류 유형: 315. 닷넷 프로파일러의 오류 코드 정보
10879정성태12/16/201521771오류 유형: 314. Error : DEP0700 : Registration of the app failed. error 0x80070005
10878정성태12/9/201524833디버깅 기술: 75. UWP(유니버설 윈도우 플랫폼) 앱에서 global::System.Diagnostics.Debugger.Break 예외 발생 시 대응 방법
10877정성태12/9/201529271VC++: 93. std::thread 사용 시 R6010 오류 [2]
10876정성태11/26/201525324.NET Framework: 541. SignedXml을 이용한 ds:Signature만드는 방법 [3]파일 다운로드1
10875정성태11/26/201530316개발 환경 구성: 279. signtool.exe의 다중 서명 기능 [2]
10874정성태11/26/201526316개발 환경 구성: 278. 인증서와 인증서를 이용한 코드 사인의 해시 구분
10873정성태11/25/201525438.NET Framework: 540. C# - 부동 소수 계산 왜 이렇게 나오죠? (2) [3]파일 다운로드1
... [121]  122  123  124  125  126  127  128  129  130  131  132  133  134  135  ...