민범규님의 글(Devpia 펌) 이 클래스는 상속될 수 없습니다 이것은 RSA의 기본 구현입니다. Microsoft Enhanced Cryptographic Provider가 설치되어 있는 경우 RSACryptoServiceProvider에서는 길이가 384 - 16384비트(8비트 단위로 증가)인 키를 지원하고 Microsoft Base Cryptographic Provider가 설치되어 있는 경우에는 길이가 384 - 512비트(8비트 단위로 증가)인 키를 지원합니다. Microsoft CAPI(Cryptographic API)와의 상호 운용
비관리 CAPI의 RSA 구현과 달리 RSACryptoServiceProvider 클래스는 암호화 후와 암호 해독 전에 바이트의 암호화된 배열에 대한 순서를 반대로 바꿉니다. 기본적으로 RSACryptoServiceProvider 클래스로 암호화된 데이터는 CAPI CryptDecrypt 함수로 암호 해독할 수 없으며 CAPI CryptEncrypt 메서드로 암호화된 데이터는 RSACryptoServiceProvider 클래스로 암호 해독할 수 없습니다. API 간 상호 운용 시 역순서 지정에 대한 보완 작업을 수행하지 않으면 RSACryptoServiceProvider 클래스가 CryptographicException을 throw합니다. CAPI와 상호 운용하려면 암호화된 데이터가 다른 API와 상호 운용되기 전에 암호화된 바이트의 순서를 직접 반대로 바꿔야 합니다. Array..::.Reverse 메서드를 호출하여 관리되는 바이트 배열의 순서를 쉽게 반대로 바꿀 수 있습니다. |
인터넷에서 찿아본 설명들
RSA는 공개키 암호시스템의 하나로, 암호화 뿐만 아니라 전자서명이 가능한 최초의 알고리즘으로 알려져 있다. RSA가 갖는 전자서명 기능은 인증을 요구하는전자 상거래 등에 RSA의 광범위한 활용을 가능하게 하였다. 1977년 로널드 라이베스트(Ron Rivest), 아디 샤미르(Adi Shamir), 레오널드 애들먼(Leonard Adleman)의 연구에 의해 체계화되었으며, RSA라는 이름은 이들 3명의 이름 앞글자를 딴 것이다. 이 세 발명자는 이 공로로 2002년 튜링상을 수상했다. RSA 암호체계의 안정성은 큰 숫자를 소인수분해하는 것이 어렵다는 것에 기반을 두고 있다. 그러므로 큰 수의 소인수분해를 획기적으로 빠르게 할 수 있는 알고리즘이 발견된다면 이 암호 체계는 가치가 떨어질 것이다. 1993년 피터 쇼어는 쇼어 알고리즘을 발표하여, 양자 컴퓨터를 이용하여 임의의 정수를 다항 시간 안에 소인수분해하는 방법을 발표하였다. 따라서 양자 컴퓨터가 본격적으로 실용화되면 RSA 알고리즘은 무용지물이 될 것이다. 그러나 양자 컴퓨터가 이 정도 수준으로 실용화되려면 아직 여러 해가 더 필요할 것으로 보인다. RSA 암호화 알고리즘은 1983년에 발명자들이 소속되어 있던 매사추세츠 공과대학교(MIT)에 의해 미국에 특허로 등록되었고, 2000년 9월 21일에 그 특허가 만료되었다 RSA는 두 개의 키를 사용한다. 여기서 키란 메시지를 열고 잠그는 상수(constant)를 의미한다. 이 중 공개키(public key)는 모두에게 알려져 있으며, 메시지를 암호화(encrypt)하는데 쓰인다. 이렇게 암호화된 메시지는 개인키(private key)를 가진 자만이 복호화(decrypt)하여 열어볼 수 있다. 다시 말하면, 누구나 어떤 메시지를 암호화할 수 있지만, 그것을 해독하여 열람할 수 있는 사람은 개인키를 지닌 단 한 사람 뿐인 것이다. RSA는 소인수분해의 난해함에 기반하여, 공개키만을 가지고는 개인키를 쉽게 짐작할 수 없도록 디자인되어 있다. 보다 이해하기 쉬운 예를 들자면, A라는 사람에게 B라는 사람이 메시지를 전하고자 할 때 B는 A의 열린 자물쇠를 들고 와 그의 메시지를 봉인하고, 그런 다음 A에게 전해 주면, 자물쇠의 열쇠를 가지고 있는 A가 그 메시지를 열어보는 식이 된다. 중간에 그 메시지를 가로채는 사람은 그 열쇠를 가지고 있지 않으므로 메시지를 열람할 수 없다. 그리고 RSA의 디자인 상, 그 열쇠는 자물쇠의 형태만 보고서는 쉽게 제작할 수가 없게 되어 있다. |
XML문서 서명 예제 //XML 서명 private void btn전자서명_Click(object sender, EventArgs e) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"; RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load(strSource); //서명 전 XML 읽기 textBox1.Text = xmlDoc.OuterXml; //서명전 파일 보기 SignedXml signedXml = new SignedXml(xmlDoc); signedXml.SigningKey = rsaKey; Reference reference = new Reference(); reference.Uri = ""; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signedXml.AddReference(reference); signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); XmlElement root = xmlDoc.DocumentElement; root.InsertAfter(xmlDoc.ImportNode(xmlDigitalSignature, true), root.FirstChild); xmlDoc.Save(strOutput); //서명한 XML생성 textBox2.Text = xmlDoc.OuterXml; } //XML 서명 private void btn서명확인_Click(object sender, EventArgs e) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"; RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load(strOutput); // SignedXml signedXml = new SignedXml(xmlDoc); XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature"); if (nodeList.Count <= 0) throw new CryptographicException("XML파일에 Signature Element는 하나만 존재하여야 합니다."); signedXml.LoadXml((XmlElement)nodeList[0]); bool result= signedXml.CheckSignature(rsaKey); if (result) textBox3.Text = "서명과 일치 합니다"; else textBox3.Text = "서명과 불칠칭 합니다."; } |