Microsoft MVP성태의 닷넷 이야기
ds:Signature 질문입니다. [링크 복사], [링크+제목 복사]
조회: 12326
글쓴 사람
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)
3667김치사발면12/15/201510777템플릿 설정 추가 질문 [1]파일 다운로드1
3666노태현12/15/201510181사용자별로 권한을 주고 볼 수 있는 데이터를 제한하려면 어떤 방법으로 접근하는게 좋을까요? [2]
3665김치사발면12/14/201513277C# 템플릿 설정이 이상해요ㅜㅜ [3]파일 다운로드1
3664KuLu12/10/201510569멀정하던 사이트 중 일부메뉴가 응답없음이 되어버립니다. [3]
3663Sung...12/10/201511965UWP 서버 프로그래밍 작업 중 [5]
3662Sung...12/9/201511809uwp앱에서 접속한 클라이언트 주소값을 받아서 표시하고 싶은데 어떤 메소드를 써야 할까요? [7]
3661김무진12/9/201511160Oracle 환경에서 데이터를 조회할때 한글이 ? 이렇게 표시가됩니다. [1]
3660질문자12/7/201513082OpenFileDialog 호출시 hang걸리는 문제 [4]
3659Sung...12/4/201512725UWP 앱에서 textBox로 클라에서 받은 값을 나타내고 싶은데 안되고 있습니다. [5]
3658강준12/3/201511971Visual Studio (Xamarin) vs Eclipse [2]
3656DEVY...12/1/201510870MasterPageFile 사용시 다국어 처리 질문입니다. [1]
3653DEVY...11/26/201512326ds:Signature 질문입니다. [7]
3654윤용한11/27/201512073    답변글 [답변]: ds:Signature 질문입니다. [3]
3657윤용한12/1/201514360    답변글 [답변]: ds:Signature 질문입니다. [1]
3651노태현11/20/201545058MariaDB - ASP.NET오류의 원인조차 못 찾고 있습니다.. [2]파일 다운로드2
3652노태현11/20/201511936    답변글 [답변]: MariaDB - ASP.NET오류의 원인조차 못 찾고 있습니다.. [3]
3649kokon11/17/201512353예제 파일 실행이 안 되네요 [5]
3647Sang...11/15/201510854Part 3 목차? [5]
3646힘찬도약11/13/201515660c# mscorlib System.IO IOException [8]파일 다운로드2
3644힘찬도약11/11/201514813c# user.config파일 [2]
3645spow...11/13/201511809    답변글 [답변]: c# user.config파일 - Json.NET을 이용한 설정파일 처리 [1]파일 다운로드1
3643힘찬도약11/11/201513611C# 함수의 processing time과 재호출 [14]
3642.net11/10/201512300c# 으로 작성된 com+ 에 대한 문제입니다. [2]
3641힘참도약11/9/201512726c# log file 관련해서 질문드립니다. [5]
3638윤창선11/4/201513300사설IP가 부여된 무선라우터간 영상전송 관련 문의 [8]
3634Hyun...11/2/201510863c# 에서 webkit browser에서 webgl을 이용하는 사이트에 접속이 안됩니다. [1]
... 46  [47]  48  49  50  51  52  53  54  55  56  57  58  59  60  ...