解密 EnvelopedCms 時不會重複解除包裝
在 macOS 和 Linux 上的 .NET Core 2.0 中,EnvelopedCms 實作會在額外的 ASN.1 OCTET STRING 值中不正確地包裝內容。 為了在處理隨此錯誤所建立的內容時維持相容性,EnvelopedCms 類別仍會查看解密的內容,並嘗試移除額外的資料。 在 Windows 上使用外部私密金鑰時,以及在所有其他作業系統上,EnvelopedCms 會在進行解密時移除額外的資料。
可惜的是,這個取巧的相容性程式碼無法區分未正確建立的文件,以及雖正確建立但具有相同資料圖形的文件。
先前的行為
先前,如果解密的內容開頭是位元組值 0x04
,而且內容中留有小於或等於位元組數目的合法編碼 ASN.1 BER 長度值,則 envelopedCms.ContentInfo.Content
屬性中提供的資料只會在視為 ASN.1 OCTET STRING 時,收到與值的內容八位元部分相關聯的資料。
例如,如果最初解密的內容是位元組數列 { 0x04, 0x03, 0x01, 0x02, 0x03 }
或 { 0x04, 0x03, 0x01, 0x02, 0x03, [continued content] }
,則 envelopedCms.ContentInfo.Content
的值是位元組數列 { 0x01, 0x02, 0x03 }
。
值的開頭如果不是 0x04
,或開頭雖是 0x04
但後面不是可接受的編碼長度值,系統便會完整報告。
對於 EnvelopedCms.Decrypt 的某些多載來說,此行為只會發生在非 Windows 作業系統上。 如需詳細資訊,請參閱受影響的 API。
新的行為
EnvelopedCms 類別不會再嘗試解決先前的問題,而是會一律如實報告解密的內容。
如果您要在 macOS 或 Linux 上處理 .NET Core 2.0 版的 EnvelopedCms 類別所建立的文件,您會在內容開頭看到額外的資料。
導入的版本
.NET 7
中斷性變更的類型
這項變更會影響二進位相容性。
變更原因
相容性程式碼無法區分未正確建立的文件,以及雖合法傳輸資料,但資料看起來像 BER 編碼 ASN.1 OCTET STRING 的文件。
由於 BER 編碼的本質,受此相容性程式碼負面影響的呼叫端無法輕易地復原其遺失的資料。
建議的動作
呼叫端所讀取的文件若是使用適用於 macOS 或 Linux 的 .NET Core 2.0 上的 EnvelopedCms 所建立的,則可以新增程式碼來移除額外的資料。 若要移除它,請使用 System.Formats.Asn1 NuGet 套件中的 AsnDecoder 類別,此套件已是 EnvelopedCms 類別的相依性。
envelopedCms.Decrypt(...);
byte[] content = envelopedCms.ContentInfo.Content;
if (envelopedCms.ContentInfo.Oid.Value == "1.2.840.113549.1.7.1")
{
if (content?.Length > 0 && content[0] == 0x04)
{
try
{
content = AsnDecoder.ReadOctetString(content, AsnEncodingRules.BER, out _);
}
catch (AsnContentException)
{
}
}
}
受影響的 API
- System.Security.Cryptography.Pkcs.EnvelopedCms.Decrypt(RecipientInfo, AsymmetricAlgorithm)
- System.Security.Cryptography.Pkcs.EnvelopedCms.Decrypt(RecipientInfo, X509Certificate2Collection) (僅限非 Windows)
- System.Security.Cryptography.Pkcs.EnvelopedCms.Decrypt(RecipientInfo) (僅限非 Windows)
- System.Security.Cryptography.Pkcs.EnvelopedCms.Decrypt(X509Certificate2Collection) (僅限非 Windows)