Microsoft MVP성태의 닷넷 이야기
ds:Signature 질문입니다. [링크 복사], [링크+제목 복사],
조회: 12358
글쓴 사람
DEVYHJ (fnlswldh at naver.com)
홈페이지
첨부 파일
 

안녕하세요 정성태님
MS사의 포럼게시판에 달아주신 답글을 확인했습니다. 감사합니다^^
전자서명관련된 작업인데 어떻게 해줘야할지 몰라서요.. 이런저런 방법들을 찾아서 해보고있는데 잘안됩니다.ㅠ_ㅠ

//개인키 불러오기    
RSAService rsa = new RSAService();
RSA rsaKey = rsa.GetRSA(priKey, "1234");        
        
//XML문서 로딩
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(new XmlTextReader(DOC));//xml파일 위치

//SignedXml 생성
SignedXml signedXml = new SignedXml(xmlDoc);
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
signedXml.SigningKey = rsaKey;

//Reference 객체
Reference reference = new Reference();
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
reference.Uri = "";
        
//정규화 설정
XmlDsigC14NTransform env1 = new XmlDsigC14NTransform();
reference.AddTransform(env1);

//XPath 필터링 설정
//문제가 되는 부분입니다. NIPA에서 XPATH값을 ds:Signature라고 정의를 해주어서 그대로 작업을 하고 있습니다. 아래와 같이 실행을 하면 ds:라는 접두사를 가진게 없다고 나옵니다.
//<ds:Signature>로 생성된게 아니라 <Signature>로 생성이 되어서 그런건데요.. 그래서 Xpath값을 ds:Signature-->Signature로 바꿔주고 서명 계산 후 Prefix를 통해 ds를 붙여 주었습니다.
//이렇게 해주면 물론 오류없이 Hash Value가 생성이 됩니다. 하지만 NIPA에서 테스트베드를 하면 Hash Value의 길이값은 같지만 전혀 다른값이 나옵니다.
//제 생각에는 Xpath에서 ds를 붙여줘야 정상적인 값이 생성되는거 같다고 보고 있어서 그 부분에 대해 해결책을 찾아가고 있습니다.
XmlDsigXPathTransform env2 =
CreateXPathTransform("not(self::*[name() = 'TaxInvoice'] | ancestor-or-self::*[name() = 'ExchangedDocument'] | ancestor-or-self::ds:Signature)");
reference.AddTransform(env2);

//Reference 추가
signedXml.AddReference(reference);

//인증서 추가
X509Certificate2 X509 = new X509Certificate2(cert);//SignCert.der 위치
KeyInfoX509Data X509Data = new KeyInfoX509Data(X509);
X509Data.AddIssuerSerial(X509.IssuerName.Name, X509.SerialNumber.ToString());
X509Data.AddSubjectName(X509.SubjectName.Name);

KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(X509Data);
signedXml.KeyInfo = keyInfo;

//서명 계산
signedXml.ComputeSignature();

//Xml 표현식으로 변경
XmlElement xmlDigitalSignature = signedXml.GetXml();
SetPrefix(xmlDigitalSignature);//하위 노드 모두에 접두사 추가

//Xml문서에 추가
XmlElement root = xmlDoc.DocumentElement;
root.InsertAfter(xmlDoc.ImportNode(xmlDigitalSignature, true), root.FirstChild);
XmlNamespaceManager xmlNmMgr = new XmlNamespaceManager(new NameTable());
xmlNmMgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
xmlDoc.SelectSingleNode("descendant::ds:XPath", xmlNmMgr).InnerText = "not(self::*[name() = 'TaxInvoice'] | ancestor-or-self::*[name() = 'ExchangedDocument'] | ancestor-or-self::ds:Signature)";

// XML 정렬 및 저장
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlDoc.OuterXml);
XmlTextWriter writer = new XmlTextWriter(RESULTDOC, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
writer.Indentation = 2;
doc.WriteTo(writer);
writer.Close();    

테스트베드를 수행하면 Digest Value결과가 아래와 같이 나옵니다. XPATH때문에 값이 다르게 나오는게 아닌가 추측하고 있는 중입니다...
사업자가 생성한 Hash Value    77qNaf19CZSkVACKOg5oXZ42kKzkomrZU+6Ruv+JhCY=
올바른 Hash Value     BL509EUfr+17Q0wPWEmXqhxa/8hqWJqnsrEnDvBlWIc=








[최초 등록일: ]
[최종 수정일: 11/26/2015]


비밀번호

댓글 작성자
 



2015-11-27 12시54분
최초 CreateXPathTransform에서 "ancestor-or-self::ds:Signature"을 사용한 것은 "not(...)"으로 포함되어 있기 때문에 서명 대상에 포함되지도 않을 뿐더러 애당초 대상 XML 문서에는 Signature 관련 노드가 없을 것이므로 선택 자체가 되지 않는 것이 맞습니다.

따라서, ComputSignature가 호출되는 당시에는 ds:Signature가 먹히든 안 먹히든 그 결과에는 변함이 없습니다. 단지 지금 문제가 되는 것은 생성된 HashValue가 다르다는 것인데요. 이 부분은 저로서도 뭐라고 말해야 될지 모르겠군요. ^^; 어쨌든 이번 문제는 XPath 지정과는 상관이 없으니 다른 곳에서 문제를 찾아보세요.
정성태
2015-11-27 12시57분
[DEVYHJ] 친절한 답변 감사드립니다^^
[guest]
2015-11-27 01시18분
참고로, "ancestor-or-self::ds:Signature"를 사용하고 싶다면 CreateXPathTransform 내에서 생성하는 XmlDocument의 XmlElement에 ds를 다음과 같이 설정해 주시면 됩니다.

// XmlDsigXPathTransform Class 문서애 나온 예제 코드 기준으로.
// ; https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.xml.xmldsigxpathtransform

            xPathElem.InnerText = XPathString;
            xPathElem.SetAttribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");

저렇게 하고 나면 xpath에 ds 접두사를 쓴 표현이 먹힐 텐데, 그래도 hash 값에는 변함이 없습니다.
정성태
2015-11-27 01시35분
어쨌든 본문의 해시 문제와는 상관없지만, XPath지정에 "ancestor-or-self::ds:Signature" 포함 여부가 아주 의미 없는 것은 아니군요. 가령 XPath에 문서의 모든 내용을 포함하라고 하면 서명할 때는 상관이 없지만, 서명 검증을 할 때는 Signature 부분도 포함이 되어 서명 검증에 실패하는 것 같습니다. 따라서 범위의 설정에 따라 "not(ancestor-or-self::ds:Signature)" 정도를 포함하는 것은 의미가 있습니다.
정성태
2015-11-27 06시17분
[윤용한] ComputeSignature() 수행먼저 하여
ds prefix 없이 수행되어서 hash 값이 다르게 나오는 것 같습니다.
ComputeSignature() 수행전에 ds prefix를 넣고 해야 하지 않을까요?
[guest]
2015-11-28 05시56분
윤용한 님, ds prefix는 hash와는 무관합니다. ds prefix가 붙는 Signature 노드는 hash 순간에는 해시를 구해야 할 대상 노드에는 없기 때문에 그것의 유무와 상관없이 해시는 동일해야 합니다. 물론 ds 네임스페이스를 해시 이후에 Signature 노드가 아닌 서명 완료된 XML 데이터 노드의 레벨에 추가하면 문제가 되겠지만 본문의 경우에는 Signature 노드에 ds 네임스페이스를 붙이기 때문에 상관없습니다.
정성태
2015-12-01 02시41분
[DEVYHJ] 두분 답변 정말 감사합니다^^ 많은걸 알아가네요 ㅎ
[guest]

... 46  47  48  49  50  51  52  53  [54]  55  56  57  58  59  60  ...
NoWriterDateCnt.TitleFile(s)
1306이상현8/7/20149981Entity 프레임웍에서 테이블만 추가로 등록하는 방법
1307이상현8/7/201410290    답변글 [답변]: 자답이네요. [1]
1305popo8/7/201411544wpf UserControl List 바인딩 질문 입니다. [1]
1304민경수8/7/201414093네이버 카페에 구글 스프레드 시트 삽입 [1]
1303김동진8/7/201411368vmware환경에서 Guest IP를 192대역으로 받을 수 있는 방법은 없을까요~? [3]
1302김문경7/31/201410505스마트클라이언트 오라클 연결 [1]
1314이재균8/20/201410553    답변글 [답변]: 스마트클라이언트 오라클 연결
1300아로스7/28/201423434c# 인터넷 임시 파일 삭제 문의 [12]파일 다운로드1
1299서동원7/28/201412016안녕하세요. 혹시 Internet_Zone과 관련된문제인가 해서 질문드립니다. [1]
1298(non...7/25/201417396(글쓴이의 요청으로 삭제합니다.) [15]
1295서동원7/22/201413103안녕하세요. 스마트클라이언트에 대해 질문드립니다. [2]파일 다운로드1
1294(non...7/20/201411487(글쓴이의 요청으로 삭제합니다.) [2]
1293VS20...7/20/201412065VS2013 Ultimate에 Windows Phone 프로젝트 템플릿 추가 방법 문의 [1]파일 다운로드2
1292(non...7/20/201410810(글쓴이의 요청으로 삭제합니다.) [2]
1291zino7/16/201411426chromium 배포본 만들기~ [1]
1290(non...7/13/201412577(글쓴이의 요청으로 삭제합니다.) [3]
1288박주만7/8/201421744C# 서비스 기반 데이터베이스(mdf) & InstallShield Limited Edition 설치 및 배포 [2]파일 다운로드1
1287김용환7/8/201419729오라클 db 사용관련 문의입니다. [4]파일 다운로드1
1286C#조으다7/8/201410705WebBrowser 공유기 관리 웹 페이지 인증 [3]
1285C#조으다7/5/201411040IE DocumentComplete 이벤트가 발생되지 않습니다. [2]
1284(non...7/4/201411171(글쓴이의 요청으로 삭제합니다.) [3]
1283김영대7/3/201414280안녕하십니까 정성태님 죄송하지만 SmartClient 에 관한 질문이 있습니다. [9]
1282(non...7/2/201411155(글쓴이의 요청으로 삭제합니다.) [2]
1281(non...7/1/201412246(글쓴이의 요청으로 삭제합니다.) [4]
1280동동이6/25/201411469안녕하세요. ocx의 비동기 또는 쓰레드에서 호출 [1]
1279(non...6/23/201411515(글쓴이의 요청으로 삭제합니다.) [17]
... 46  47  48  49  50  51  52  53  [54]  55  56  57  58  59  60  ...