Microsoft MVP성태의 닷넷 이야기
ds:Signature 질문입니다. [링크 복사], [링크+제목 복사],
조회: 12348
글쓴 사람
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)
1556김응규4/22/201512222    답변글 [답변]: WCF net.tcp 관련해서 질문 드립니다. [1]파일 다운로드1
1554(삭제)4/19/201512981안드로이드 에뮬레이터에서 특정 앱 구동불가할때! [2]
1552spow...4/18/201518902마이크로세컨드 단위의 Sleep이 필요한데 찾질 못하겠습니다. [5]
1553spow...4/18/201512177    답변글 [답변]: 마이크로세컨드 단위의 Sleep이 필요한데 찾질 못하겠습니다. [1]
1551인디언기...4/16/201511576iisnode에 대해서 글 올리셨던데 질문이 있습니다 [1]
1549김선아4/15/201512028.net framework 4.5와 c++ dll에 관한 질문입니다 [1]
1550김선아4/15/201510445    답변글 [답변]: .net framework 4.5와 c++ dll에 관한 질문입니다 [2]
1547문명식4/3/201512464IWebBrowser Key Event 관련 [2]
1545나종식3/25/201511430internet explorer dns cache flush [2]
1543이용원3/23/201511437hyper-v 질문드려요! [1]
1544이용원3/24/201510556    답변글 한가지만 더 여쭤볼게요! [1]
1541임기성3/20/201517788Microsoft.Office.Core dll관련 문제 [1]
1539펜플3/17/201511117asp.net 질문입니다. [1]
1540113/17/201511116    답변글 [답변]: asp.net 질문입니다. [1]
1538열공합시닷3/13/201511884중계서버 질문드립니다 [1]
1537김재영3/11/201512955asp.net의 빌드 유휴시간 이후의 리빌드 작업을 컨트롤 할 수 있습니까? [2]
1536솔솔3/9/201511396mac address얻으려고 하는데요.. [1]
1535Stud...3/4/201511949C#엔 MFC의 theApp 과 같은 기능을 하는것이 없나요? [3]
1534김동진3/4/201511389C#에서 BHO로 Windows Explorer에서의 동작이 가능할지요 [2]
1533김동현3/3/201511668컴파일 된 프로그램에 코드 삽입(?) 관련입니다. [1]
1532반가워요3/3/201514267C# 소켓연결에 packet송수신... [8]
1531강현수3/2/201512912C# com 등록 시 GUID 변경 관련 문의 [1]
1529김민규2/15/201512785C++ 64bit/32bit [3]파일 다운로드1
1528김개똥2/14/201510278좀 관련없는 질문이지만, 정말 답답하고 찾는데 명확한 해답 찾지못해 질문 올립니다. <Windows 사용자 인증> [1]
1527방문자1/27/201511331System Timer의 Tick에서 Backgroundworker를 호출하면 스레드 문제가 있을까요? [1]
1526황상대1/26/201513145C# 마샬링 관련 질문이 있습니다. [1]
... 46  47  48  49  50  [51]  52  53  54  55  56  57  58  59  60  ...