繁体   English   中英

在Silverlight中访问X509Store

[英]Accessing the X509Store in Silverlight

我目前正在开发一个Silverlight应用程序,以便访问X509Store,使用嵌入到USB安全令牌中的私钥对数据进行签名。

我从一个以这种方式工作的C#应用​​程序开始:

public byte[] SignData(byte[] HashTosign, string Cert_To_Use_b64)
{
    byte[] Signature = null;

    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
    X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
    store.Close();

    try {
        foreach (X509Certificate2 Certificate in collection) {

            if (ToBase64(Certificate.RawData) == Cert_To_Use_b64) {

                RSACryptoServiceProvider Rsa = new RSACryptoServiceProvider();
                Rsa = (RSACryptoServiceProvider)Certificate.PrivateKey;

                try {
                    RSACryptoServiceProvider aesRsa = new RSACryptoServiceProvider();
                    string strPk = Certificate.PrivateKey.ToXmlString(true);
                    aesRsa.FromXmlString(strPk);
                    Signature = aesRsa.SignHash(HashTosign, CryptoConfig.MapNameToOID("SHA256"));


                } catch (Exception ex) {
                    Throw new exception("FAILURE : " + ex.Message());
                }


                lgSignature = Signature.Length;
                return 0;
            }
        }
    } catch (CryptographicException ex) {
        Throw new exception("FAILURE : " + ex.Message());
    } catch (Exception ex) {
        Throw new exception("FAILURE : " + ex.Message());
    }
}

该方法在C#应用程序中运行良好。 但是当我尝试将其改编为Silverlight时,X509Store似乎没有实现。

The name “X509Store” does not exist in the namespace System.Security.Cryptography. Are you missing an assembly reference?

我试图应用.NET Framework DLL,但我收到以下错误:

It is not possible to add a reference to System.Security.dll because it was not created with the Silverlight runtime. Silverlight projects only work with Silverlight assemblies.

我可以将System.Security.dll程序集重新创建到Silverlight吗? 或者有更好的方法来做我想做的事情吗?

提前致谢。

有两种方法可以做你想要的:


CryptoAPI通过P / Invoke

我的第一个猜测是使用本机Windows库crypt32.dll(通常称为CryptoApi)。 毕竟System.Security.dll只是一个托管包装器(使用像ILSpy这样的工具浏览反编译源将向您展示MS如何包装它)。 在提升信任(属性 - > Silverlight - >需要提升信任)和管理员权限(能够打开证书存储区)中运行时,可以在Silverlight中使用P / Invoke。 然而,有几个缺点:

  • 这是相当不友好的(让我回到旧的好的C / C ++天)
  • 您需要在低级系统结构和操作(如指针)上操作
  • 您需要将此样式用于证书检索和签名计算

文档参考:

这样我就设法获得了在我的智能卡上注册的证书的句柄(IntPtr指针):

using System;
using System.Runtime.InteropServices;

namespace SilverlightX509Store
{
    public static class CapiNative
    {
        public const string MY = "MY";
        public const uint PKCS_7_ASN_ENCODING = 0x00010000;
        public const uint X509_ASN_ENCODING = 0x00000001;
        public const uint CERT_FIND_SUBJECT_STR = 0x00080007;
        public const int ACCESS_DENIED = 5;

        [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CertOpenSystemStore(
            IntPtr hCryptProv,
            string storename);

        [DllImport("crypt32.dll", SetLastError = true)]
        public static extern IntPtr CertFindCertificateInStore(
            IntPtr hCertStore,
            uint dwCertEncodingType,
            uint dwFindFlags,
            uint dwFindType,
            [In, MarshalAs(UnmanagedType.LPWStr)]String pszFindString,
            IntPtr pPrevCertCntxt);
    }

    public class CapiWrapper
    {
        public IntPtr FindCert(string subject)
        {
            IntPtr storeHandle = CapiNative.CertOpenSystemStore(
                IntPtr.Zero, 
                CapiNative.MY);

            if (Marshal.GetLastWin32Error() == CapiNative.ACCESS_DENIED)
            {
                return IntPtr.Zero;
            }

            IntPtr certHandle = CapiNative.CertFindCertificateInStore(
                storeHandle,
                CapiNative.PKCS_7_ASN_ENCODING | CapiNative.X509_ASN_ENCODING,
                0,
                CapiNative.CERT_FIND_SUBJECT_STR,
                "subject to find",
                IntPtr.Zero);

            return certHandle;
        }
    }
}

将.NET dll转换为Silverlight兼容

似乎有一种方法可以将.NET库转换为SL。 请参阅Silverlight中重用.NET程序集的文章。 我还没有测试过。 潜在的问题可能是.NET安全端加密深入到mscorlib和System.Security中,并且转换这些库可能并不那么容易(甚至根本不可能)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM