ãã ãããã¡ã€ã«ããµãŒããŒäžã«ãããã¯ã©ã€ã¢ã³ãå šäœãé§åããã«ãã©ãã£ãã¯ãæå°éã«æããŠçœ²åãããå Žåã¯ã©ãã§ããããïŒ
é¢çœãïŒ
ãããã£ãŠãã¯ã©ã€ã¢ã³ã/ãµãŒããŒXMLDSigããžã¿ã«çœ²åçæã¢ã«ãŽãªãºã ã
XMLDsigã®ä»æ§æ å ±ã¯ãã¡ãã«ãããŸã ã
XMLããã¥ã¡ã³ãã®ãšã³ãããŒã眲åã®åœ¢æãæ€èšããŸãã
眲åãããxmlã®ç°¡åãªäŸïŒ
<MyTestXml> <MySomeData>....</MySomeData> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /> <SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411" /> <Reference URI=""> <Transforms> <Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> <XPath xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">not(ancestor-or-self::dsig:Signature)</XPath> </Transform> </Transforms> <DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411" /> <DigestValue>...</DigestValue> </Reference> </SignedInfo> <SignatureValue>...</SignatureValue> <KeyInfo> <X509Data> <X509Certificate>...</X509Certificate> </X509Data> </KeyInfo> </Signature> </MyTestXml>
ãšã³ãããŒã眲åãšã¯äœããããããç解ããããã«ãä»æ§ããã¿ã°ã®èª¬æãç°¡åã«ç¿»èš³ããããšããå§ãããŸãã
- 眲å-眲åèªäœãšèšŒææžãå«ã眲åããŒã¿ãå«ãŸããŸãã
- SignedInfo-眲åãããŠããããŒã¿ãšã眲åãçæãããšãã«äœ¿çšãããã¢ã«ãŽãªãºã ã«é¢ããæ å ±ãå«ãŸããŠããŸãã
- CanonicalizationMethod-眲åãèšç®ããåã«SignedInfoã«é©çšãããcanalizationã¢ã«ãŽãªãºã ãæå®ããŸãã
- SignatureMethod-眲åã®çæãšæ€èšŒã«äœ¿çšãããã¢ã«ãŽãªãºã ã瀺ããŸãã æ£èŠåãããSignedInfoã¿ã°ã¯ãã¢ã«ãŽãªãºã ã®å ¥åã«ãªããŸãã
- åç §-1å以äžçºçããå ŽåããããŸãã ããã¥ã¡ã³ãå ã®ããŒã¿ã®å ŽæãããŒã¿ããããã·ã¥ãèšç®ããã¢ã«ãŽãªãºã ãå€æãããã·ã¥èªäœãªã©ã眲åãããŠããããŒã¿ã«é¢ããæ å ±ãå«ãŸããŠããŸãã
- ããŒã¿ã«å¯Ÿããå€æããã³å€æã®å€æã Referenceã¿ã°ã®URIå±æ§ãéåç §ããçµæã¯ãæåã®å€æã®å ¥åã«ãªããŸãã åã®å€æã®çµæã¯åŸç¶ã®åå€æã®å ¥åã«ãªããæåŸã®å€æã®çµæã¯DigestMethodã§æå®ãããã¢ã«ãŽãªãºã ã®å ¥åã«ãªããŸãã éåžžãå€æã§ã¯ãä¿è·ããããã¥ã¡ã³ãã®éšåãå®çŸ©ããXPathãæå®ããŸãã
- DigestMethodã¯ãå€æçµæããã®ããã·ã¥èšç®ã¢ã«ãŽãªãºã ã§ãã
- DigestValueã¯ãTransformsã®çµæããã®ããã·ã¥å€ã§ãããå€ãã®å Žåãåç §URIãæãããŒã¿ããã®ããã·ã¥å€ã§ãã
- SignatureValue-ãã¹ãŠãèãåºãããããã®çœ²åãã®ãã®ã
- KeyInfo-ããŒã«é¢ããæ å ±ãããã§ã¯ãX509Certificateã¿ã°ãé¢å¿ãæã£ãŠããŸããããã«ã¯ãããŒã¿ã眲åãããŠããããŒããã®base64encoded蚌ææžãå«ãŸããŠããŸãã
ãããã£ãŠããœãŒã¹ããŒã¿ïŒ
- ãµãŒããŒã«ã¯çœ²åãå¿ èŠãªxml-documentããããŸãã ãµãŒããŒã§CryptoPro .Netã䜿çšããŸãããããããªãã§ãå¯èœã§ãã
- ã¯ã©ã€ã¢ã³ãã«ã¯ãCryptoPro CSp 3.6ïŒç§ã®å Žåã¯Windows 7ïŒã§ã®åäœããµããŒãããOSãCryptoPro EDS Browser Pluginã§ã®åäœããµããŒããããã©ãŠã¶ãŒããããŠå®éã«çœ²åããããŒïŒç§ã®å ŽåãããŒã¯USBãã©ãã·ã¥ãã©ã€ãã«ãããŸããïŒãå¿ èŠã§ãã
ã¯ã©ã€ã¢ã³ãã®æºåïŒ
- CryptoPro CSP 3.6ãã€ã³ã¹ããŒã«ããŸã
- CryptoPro EDS Browser Pluginãã€ã³ã¹ããŒã«ããŸã
- 蚌ææžããã©ãã·ã¥ãã©ã€ãããããŒã«ã«ã¹ãã¬ãŒãžã«ã€ã³ã¹ããŒã«ããŸãïŒ æé ãåç
§
ãã©ã°ã©ãã2.5.2.2ã ç§å¯éµã³ã³ããã«ä¿åãããå人蚌ææžãã€ã³ã¹ããŒã«ãããïŒ
ã¹ãããçªå·1ã ïŒãµãŒããŒïŒ
眲åããããã¥ã¡ã³ãã®çœ²åãã³ãã¬ãŒããæºåããŠããŸãã
ãã®æ®µéã§ãä¿è·ãããããŒã¿ããèšç®ãããããã·ã¥ïŒDigestValueïŒãå«ãSignatureã¿ã°ã®ãã©ãããååŸããå¿ èŠããããŸãã ãããã®ããã·ã¥ãæåã§èšç®ããã¢ã«ãŽãªãºã ã®è©³çŽ°ã¯ããã§èª¬æããŸãããCryptoPro .Netãç§ãã¡ã®ãªãã£ã¹ã§è³Œå ¥ãããããã«åºã¥ããŠçœ²åãåŠçããããã®å éšã©ã€ãã©ãªãäœæãããããããã®ã©ã€ãã©ãªã䜿çšããŠå¥ã®ããŒã§ãµãŒããŒäžã®ããã¥ã¡ã³ãã«åçŽã«çœ²åããçµæãšããŠåžæãåãåããŸããããŒã¿ããèšç®ãããããã·ã¥ãæã€ãã³ãã¬ãŒãã§ãããSignatureValueãšX509Certificateãç¡å¹ã§ãã
ã¹ãããçªå·2ã ïŒãµãŒããŒïŒ
æé 1ã§äœæãããSignedInfoãæ£èŠåãã
ã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãïŒ ããããè¿œå ãããŠããŸã ãè«äºã®å Žæã«æ®ã£ãŠããã®ã¯å ã®ããã¹ãã§ãïŒã
- æåã®æåã<ããæåŸã®ã>ãã
- ã¿ã°å ã®ãã¹ãŠã®äžéã¹ããŒã¹æåã¯ä¿æãããŸãïŒå ã®ãã¹ãŠã®å è¡ã¹ããŒã¹æåã¯ä¿æãããŸãïŒã
- èŠçŽ ãèŠã
<tag />
<tag></tag>
- è¡æ«ã¯LFïŒ0x0AïŒã«çœ®ãæããããŸãã
- åå空éxmlns = " www.w3.org/2000/09/xmldsig# "ãSignedInfoã¿ã°ã«èšå®ããŸãïŒè±èªã®ãªãªãžãã«åå空éxmlns = " www.w3.org/2000/09/xmldsig# "ã¯èŠªSignatureèŠçŽ ããäŒæãããŸãã ïŒ
- ã¿ã°å±æ§ã¯ãã¢ã«ãã¡ãããé ã«ã¿ã°å ã«é 眮ããå¿ èŠããããŸãïŒSignaturePropertiesãå«ã眲åãäœæãããšããã®åé¡ãæããã«ãªããŸãïŒ
ç§ã®å Žåã«æ©èœããCïŒã³ãŒãïŒ
XmlNode xmlNode = xmlElement.GetElementsByTagName("SignedInfo")[0]; XmlDocument xmlDocumentSignInfo = new XmlDocument(); xmlDocumentSignInfo.PreserveWhitespace = true; xmlDocumentSignInfo.LoadXml(xmlNode.OuterXml); result = Canonicalize(xmlDocumentSignInfo);
ããã§ïŒ
public string Canonicalize(XmlDocument document) { XmlDsigExcC14NTransform xmlTransform = new XmlDsigExcC14NTransform(); xmlTransform.LoadInput(document); string result = new StreamReader((MemoryStream)xmlTransform.GetOutput()).ReadToEnd(); //C# XPath result = s.Replace("<XPath>", "<XPath xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">"); return result ; }
ã¹ãããçªå·3ã
æ£èŠåãããSignedInfoããããã·ã¥ãååŸããŸãã
ãµãŒããŒãšã¯ã©ã€ã¢ã³ãã®2ã€ã®ãªãã·ã§ã³ããããŸãã
3.1ïŒã¯ã©ã€ã¢ã³ãã§ããã·ã¥ãååŸããŸãã ç§ã¯ããã䜿çšããã®ã§ãæåã«èª¬æããŸãã
ãµãŒããŒã§ãcanalized SignedInfoãbase64ã§ãšã³ã³ãŒãããŸã
CïŒïŒ
string b64CanonicalizeSignedInfo= Convert.ToBase64String(Encoding.UTF8.GetBytes(s));
ãã®ããŒã¿ãã¯ã©ã€ã¢ã³ãã«éä¿¡ããŸãã
ã¯ã©ã€ã¢ã³ãã§ã¯ãæå·åãªã¯ãšã¹ããã©ã°ã€ã³ã®å©ããåããŠããã·ã¥ãååŸããŸã
JavaScriptïŒ
var CADESCOM_HASH_ALGORITHM_CP_GOST_3411 = 100; var CADESCOM_BASE64_TO_BINARY = 1; var hashObject = CreateObject("CAdESCOM.HashedData"); hashObject.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411; hashObject.DataEncoding = CADESCOM_BASE64_TO_BINARY; hashObject.Hash(hexCanonicalSignedInfo);
hashObject.Valueã䜿çšããŠããã·ã¥ã衚瀺ã§ããŸã
3.2ïŒãµãŒããŒã§ããã·ã¥ãèªã¿åããã¯ã©ã€ã¢ã³ãã«éä¿¡ããŸãã ãã®ãªãã·ã§ã³ã¯ç§ã«ãšã£ãŠã¯ããŸããããŸããã§ããããæ£çŽãªãšãããç§ã¯æ¬åœã«è©ŠããŸããã§ããã
ããã·ã¥ãåãïŒCïŒãµãŒããŒïŒïŒ
HashAlgorithm myhash = HashAlgorithm.Create("GOST3411"); byte[] hashResult = myhash.ComputeHash(anonicalSignedInfoByteArr);
ãããããããã·ã¥ãbase64ã«å€æããå¿ èŠããããŸãã
ã¯ã©ã€ã¢ã³ãã«éä¿¡ããããã§äœ¿çšããŸã
var hashObject = CreateObject("CAdESCOM.HashedData"); hashObject.SetHashValue(hashFromServer);
hashObject.SetHashValueã¡ãœããã§ãšã©ãŒãçºçããŸããã ç§ã¯ç解ããŠããŸããã§ããããæå·ãã©ãŒã©ã ã¯ã圌ããäœããã®åœ¢ã§ãããæ©èœãããããšãã§ãããšèšããŸãã
ãµãŒããŒåŽã®ããã·ã¥çæã¢ã«ãŽãªãºã ã®å®è£ ãèšç»ããŠããå Žåãããã€ãã®äŸ¿å©ãªãã³ãã以äžã«ç€ºããŸãã
1ïŒç©ºã®è¡ããã¯ã©ã€ã¢ã³ããšãµãŒããŒã®ããã·ã¥ãæ°ããŸãã äžèŽããå¿ èŠããããŸããã€ãŸããã¢ã«ãŽãªãºã ã¯åãã§ãã
GOST3411ã®å Žåããããã¯æ¬¡ã®å€ã§ãã
base64ïŒmB5fPKMMhBSHgw + E + 0M + E6wRAVabnBNYSsSDI0zWVsA =
hexïŒ98 1e 5f 3c a3 0c 84 14 87 83 0f 84 fb 43 3e 13 ac 11 01 56 9b 9c 13 58 4a c4 83 23 4c d6 56 c0
2ïŒã¯ã©ã€ã¢ã³ããšãµãŒããŒã§çæãããä»»æã®ããŒã¿ã®ããã·ã¥ãäžèŽããããšã確èªããŠãã ããã
ãã®åŸãSignedInfoå šäœã§ã¯ãªããSignedInfoããã®ããã·ã¥ã®ã¿ãã¯ã©ã€ã¢ã³ãã«éä¿¡ã§ããŸãã
ã¹ããã4ãïŒã¯ã©ã€ã¢ã³ãïŒ
SignatureValueãçæããSignatureValueãµãŒããŒãšèšŒææžæ å ±ã«éä¿¡ããŸã
var certNumber=2; // var CAPICOM_CURRENT_USER_STORE = 2; var CAPICOM_MY_STORE = "my"; var CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2; var oStore = CreateObject("CAPICOM.Store"); oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED); var certificate=oStore.Certificates.Item(certNumber) var rawSignature = CreateObject("CAdESCOM.RawSignature"); var signatureHex = rawSignature.SignHash(hashObject, certificate); // base64 var binReversedSignatureString = utils.reverse(utils.hexToString(signatureHex)); var certValue = certificate.Export(certNumber);
ãµãŒããŒbinReversedSignatureStringããã³certValueã«æ»ããŸãã
utilsããé¢æ°ã³ãŒããã¢ããããŒãããŸããã 圌ãã¯cryptoProãã©ãŒã©ã ã§ç§ã«èšã£ããããªãã¯ãã®ã¹ã¬ããã§ãããèŠãããšãã§ããŸã
ã¹ãããçªå·5ã ïŒãµãŒããŒïŒ
ã¹ãããïŒ1ã§çæãããSignatureã¿ã°å ã®SignatureValueã¿ã°ãšX509Certificateã¿ã°ããã¯ã©ã€ã¢ã³ãããåãåã£ãå€ã«çœ®ãæããŸã
ã¹ãããçªå·6ã ïŒãµãŒããŒïŒ
ã«ãŒãã確èªããŸãã
æ€èšŒãæåããå Žåããã¹ãŠãæ£åžžã§ãã ãã®çµæããã¡ã€ã«èªäœãååŸã«è¿œè·¡ããã«ãã¯ã©ã€ã¢ã³ãããŒã§çœ²åãããããã¥ã¡ã³ãããµãŒããŒäžã§ååŸããŸãã
泚ïŒæ¢ã«çœ²åãå«ãŸããŠããããã¥ã¡ã³ãã§äœæ¥ããŠããå Žåã¯ãæé 1ã®åã«ããã¥ã¡ã³ãããåæããæé 6ã®åŸã«ããã¥ã¡ã³ãã«æ·»ä»ããå¿ èŠããããŸãã
çµè«ãšããŠãCryptoPro dmishin and Fomichãã©ãŒã©ã ã®åå è ãã¢ã«ãŽãªãºã ãèŠã€ããã®ãæ¯æŽããŠããã ããããããšãããããŸãã
圌ãã®ã¢ããã€ã¹ããªããã°ãç§ã¯ããã§äœåãé·ã倱æããã§ãããã