質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

0回答

761閲覧

XAdES-BES形式の署名をRSA SHA256で行いたい

h-satou

総合スコア6

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2022/12/20 02:12

編集2022/12/22 07:59

前提

C#で内部detached形式、XAdES-BES形式の署名を行うシステムを作成しています。
署名をRSA SHA256で行いたいのですが、署名の際に、

System.Security.Cryptography.CryptographicException
無効なアルゴリズムが指定されました。

と、例外が発生してしまいます。

実現したいこと

指定した証明書から取得した秘密キーでの署名をRSA SHA256で行う。

発生している問題・エラーメッセージ

無効なアルゴリズムが指定されました。

該当のソースコード

C#

1using System; 2using System.Collections.Generic; 3using System.Xml; 4using System.Security.Cryptography; 5using System.Security.Cryptography.Xml; 6using System.Security.Cryptography.X509Certificates; 7 8namespace XmlSignTest 9{ 10 public class MySignedXml : SignedXml 11 { 12 private readonly List<DataObject> dataObjects = new List<DataObject>(); 13 14 public MySignedXml(XmlDocument document):base(document){} 15 16 public override XmlElement GetIdElement(XmlDocument document, string idValue) 17 { 18 if (string.IsNullOrEmpty(idValue)) 19 { 20 return null; 21 } 22 23 XmlElement elem = base.GetIdElement(document, idValue); 24 if (null != elem) 25 { 26 return elem; 27 } 28 29 foreach (DataObject data in dataObjects) 30 { 31 elem = findNodeWithAttributeValueIn(data.Data, "Id", idValue); 32 if (null != elem) 33 { 34 return elem; 35 } 36 } 37 38 if (base.KeyInfo != null) 39 { 40 elem = findNodeWithAttributeValueIn(base.KeyInfo.GetXml().SelectNodes("."), "Id", idValue); 41 if (null != elem) 42 { 43 return elem; 44 } 45 } 46 47 return null; 48 } 49 50 public new void AddObject(DataObject data) 51 { 52 base.AddObject(data); 53 dataObjects.Add(data); 54 } 55 56 public XmlElement findNodeWithAttributeValueIn(XmlNodeList nodeList, string attributeName, string value) 57 { 58 if (nodeList.Count == 0) 59 { 60 return null; 61 } 62 63 foreach (XmlNode node in nodeList) 64 { 65 XmlElement nodeWithSameId = findNodeWithAttributeValueIn(node, attributeName, value); 66 if (nodeWithSameId != null) 67 { 68 return nodeWithSameId; 69 } 70 } 71 return null; 72 } 73 74 private XmlElement findNodeWithAttributeValueIn(XmlNode node, string attributeName, string value) 75 { 76 string attributeValueInNode = getAttributeValueInNodeOrNull(node, attributeName); 77 if ((attributeValueInNode != null) && (attributeValueInNode.Equals(value))) 78 { 79 return (XmlElement)node; 80 } 81 return findNodeWithAttributeValueIn(node.ChildNodes, attributeName, value); 82 } 83 84 private string getAttributeValueInNodeOrNull(XmlNode node, string attributeName) 85 { 86 if (node.Attributes != null) 87 { 88 XmlAttribute attribute = node.Attributes[attributeName]; 89 if (attribute != null) 90 { 91 return attribute.Value; 92 } 93 } 94 return null; 95 } 96 } 97 98 class Program 99 { 100 static void Main(string[] args) 101 { 102 XmlDocument doc = new XmlDocument(); 103 104 doc.PreserveWhitespace = true; 105 doc.Load("test.xml"); 106 107 MySignedXml sxml = new MySignedXml(doc); 108 109 Signature sig = sxml.Signature; 110 sig.Id = "TestSign"; 111 112 sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; 113 sxml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA256Url; 114 115 Reference refer = new Reference(); 116 refer.Uri = "#TestDocument"; 117 refer.DigestMethod = SignedXml.XmlDsigSHA256Url; 118 119 Reference refer2 = new Reference(); 120 refer2.Uri = "#SignedProperties01"; 121 refer2.Type = "http://uri.etsi.org/01903#SignedProperties"; 122 refer2.AddTransform(new XmlDsigC14NTransform()); 123 refer2.DigestMethod = SignedXml.XmlDsigSHA256Url; 124 125 Reference refer3 = new Reference(); 126 refer3.Uri = "#KeyInfo01"; 127 refer3.AddTransform(new XmlDsigC14NTransform()); 128 refer3.DigestMethod = SignedXml.XmlDsigSHA256Url; 129 130 X509Certificate2 cert = null; 131 X509Store store = new X509Store(StoreName.My); 132 store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 133 X509Certificate2Collection certCollection = store.Certificates; 134 X509Certificate2Collection foundCert = certCollection.Find(X509FindType.FindByIssuerName, "Issuer-Name", true); 135 cert = foundCert[0]; 136 store.Close(); 137 138 sxml.SigningKey = cert.PrivateKey; 139 140 KeyInfo key = new KeyInfo(); 141 key.Id = "KeyInfo01"; 142 key.AddClause(new KeyInfoX509Data(cert)); 143 sxml.KeyInfo = key; 144 145 XmlElement qpElem = doc.CreateElement("xa132", "QualifyingProperties", "http://uri.etsi.org/09103/v1.3.2#"); 146 qpElem.SetAttribute("Target", "#TestSign"); 147 XmlElement spElem = doc.CreateElement("xa132", "SignedProperties", "http://uri.etsi.org/09103/v1.3.2#"); 148 spElem.SetAttribute("Id", "SignedProperties01"); 149 XmlElement sspElem = doc.CreateElement("xa132", "SignedSignatureProperties", "http://uri.etsi.org/09103/v1.3.2#"); 150 151 spElem.AppendChild(sspElem); 152 qpElem.AppendChild(spElem); 153 154 DataObject obj = new DataObject(); 155 obj.Data = qpElem.SelectNodes("."); 156 sxml.AddObject(obj); 157 158 sxml.AddReference(refer); 159 sxml.AddReference(refer2); 160 sxml.AddReference(refer3); 161 162 sxml.ComputeSignature(); // ここで例外発生 163 164 XmlElement xmlDigitalSignature = sxml.GetXml(); 165 166 XmlNode node = doc.SelectSingleNode("Document/Test/TestSign"); 167 node.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); 168 169 doc.Save("signed.xml"); 170 171 doc.Load("signed.xml"); 172 sxml = new MySignedXml(doc); 173 XmlNodeList nodelist = doc.GetElementsByTagName("Signature"); 174 sxml.LoadXml((XmlElement)nodelist[0]); 175 bool b = sxml.CheckSignature(cert, true); 176 if (b) 177 { 178 System.Windows.Forms.MessageBox.Show("valid."); 179 } 180 else 181 { 182 System.Windows.Forms.MessageBox.Show("not valid."); 183 } 184 185 } 186 } 187} 188

試したこと

  • sxml.SignedInfo.SignatureMethod の値を SignedXml.XmlDsigRSASHA1Url にすると、例外が発生せずにPIN入力のダイアログが表示され、PIN入力後に署名付きのXMLファイルが生成されましたが、<SignatureMethod>のAlgorithm属性の値が "http://www.w3.org/2000/09/xmldsig#rsa-sha1" になってしまいました。

  • sxml.SigningKeyの取得方法を以下のようにしたところ、<SignatureMethod>のAlgorithm属性の値は"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" になりましたが、PIN入力のダイアログが表示されませんでした。PINを設定している箇所はどこにもないので、この署名ではダメだと思われます。

C#

1RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey; 2CspParameters csp = new CspParameters(); 3csp.ProviderName = null; 4csp.ProviderType = 24; 5csp.KeyNumber = (int)rsa.CspKeyContainerInfo.KeyNumber; 6csp.KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName; 7RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider(csp); 8sxml.SigningKey = rsa2;

どちらもCheckSignature()の結果はfalseでした。
PINを設定してかつ、<SignatureMethod>のAlgorithm属性の値を"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" にしたいです。

2022/12/22 追記
取得した証明書の PrivateKey.SignatureAlgorithm プロパティの値を確認したところ、"http://www.w3.org/2000/09/xmldsig#rsa-sha1" となっていました。何か関係があるのでしょうか?

補足情報(FW/ツールのバージョンなど)

署名するXMLファイルは以下のようになっています。
<TestSign></TestSign>の間に署名が入ります。

XML

1<?xml version="1.0" encoding="utf-8"?> 2<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Document" xsi:noNamespaceSchemaLocation="EP.xsd"> 3 <Test> 4 <TestDocument id="TestDocument">testtesttest</TestDocument> 5 <TestSign> 6 </TestSign> 7 </Test> 8</Document>

OS Windows7 Professional SP1
開発ツール Visual Studio 2017
ターゲットフレームワーク .NET Framework 4.8

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問