성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>openssl의 PEM 개인키 파일을 .NET RSACryptoServiceProvider에서 사용하는 방법</h1> <p> 키 파일의 형식이 참 다양합니다. ^^ 예전 글에서 다뤘던,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > (공개키를 담은) 자바의 key 파일을 닷넷의 RSACryptoServiceProvider에서 사용하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1401'>http://www.sysnet.pe.kr/2/0/1401</a> </pre> <br /> 자바의 키 파일은 완전히 바이너리 형식이었고, openssl의 "genrsa" 옵션으로 생성하는 키 파일은 PEM 형식의 텍스트입니다. 한번 볼까요? ^^ 다음과 같이 명령행에서 "openssl genrsa [keysize]"와 같이 실행하면 화면에 PEM 형식의 개인키가 출력됩니다.<br /> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > D:\Tools\cert\openssl\bin><span style='color: blue; font-weight: bold'>openssl genrsa 4096</span> Loading 'screen' into random state - done Generating RSA private key, 4096 bit long modulus ......++ .......................++ unable to write 'random state' e is 65537 (0x10001) -----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY----- </pre> <br /> 그럼, "-----BEGIN RSA PRIVATE KEY-----"과 "-----END RSA PRIVATE KEY-----"을 포함한 그 사이의 출력 결과를 파일로 저장한 후 닷넷의 RSACryptoServiceProvider로 연결하면 됩니다.<br /> <br /> 문제는, 닷넷의 BCL에서는 PEM 파일을 읽는 기능이 없다는 것입니다. 따라서 이번에도 "<a target='tab' href='http://www.sysnet.pe.kr/2/0/1401'>(공개키를 담은) 자바의 key 파일을 닷넷의 RSACryptoServiceProvider에서 사용하는 방법</a>" 글에 소개했던 "<a target='tab' href='http://www.bouncycastle.org/csharp/'>Bouncy Castle</a>" 라이브러리를 이용해야 합니다.<br /> <br /> 그래도 ^^ 세상이 많이 좋아져서 Nuget 콘솔 창에서 다음과 같이 입력만 해주시면 다운로드 및 참조까지 다 되어 한방에 사용 준비가 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > PM> <span style='color: blue; font-weight: bold'>Install-Package BouncyCastle </span> </pre> <br /> 이제 PEM 키 파일 변환은 다음과 같이 해주시면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > RSACryptoServiceProvider rsa = LoadKey("key.txt"); private static RSACryptoServiceProvider LoadKey(string keyFilePath) { Org.BouncyCastle.OpenSsl.PemReader pem = new Org.BouncyCastle.<span style='color: blue; font-weight: bold'>OpenSsl.PemReader</span>(File.OpenText(keyFilePath)); Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair rsaParameters = pem.ReadObject() as Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair; Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters key = rsaParameters.Private as Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters; <span style='color: blue; font-weight: bold'>RSAParameters netrsa = DotNetUtilities.ToRSAParameters(key); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportParameters(netrsa);</span> return rsa; } </pre> <a name='rsa_enc_dec'></a> <br /> 정상적으로 로드되었다면 다음과 같은 암호화/복호화 테스트가 잘 수행이 됩니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // RSACryptoServiceProvider로 암/복호화 테스트 UnicodeEncoding ByteConverter = new UnicodeEncoding(); byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt"); byte[] encryptedData; byte[] decryptedData; encryptedData = RSAEncrypt(dataToEncrypt, rsa.ExportParameters(false), false); decryptedData = RSADecrypt(encryptedData, rsa.ExportParameters(true), false); Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData)); static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding) { try { byte[] encryptedData; using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider()) { RSA.ImportParameters(RSAKeyInfo); encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding); } return encryptedData; } catch (CryptographicException e) { Console.WriteLine(e.Message); return null; } } static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding) { try { byte[] decryptedData; using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider()) { RSA.ImportParameters(RSAKeyInfo); decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding); } return decryptedData; } catch (CryptographicException e) { Console.WriteLine(e.ToString()); return null; } } </pre> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1004&boardid=331301885'>첨부한 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> <br /> 참고로, PEM 파일로부터 .pfx 파일 만드는 것과 Java .keystore 파일에 저장된 개인키가 pem 형식으로 나오는 등의 내용을 다음의 글에서 상세하게 보실 수 있습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .keystore 파일에 저장된 개인키 추출방법과 인증기관으로부터 온 공개키를 합친 pfx 파일 만드는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1262'>http://www.sysnet.pe.kr/2/0/1262</a> JKS(Java Key Store)에 저장된 인증서를 ActiveX 코드 서명에 사용하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/882'>http://www.sysnet.pe.kr/2/0/882</a> </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6294
(왼쪽의 숫자를 입력해야 합니다.)