2010-07-19 44 views
3

我想嵌入一些C#.Net代码,在网页中执行一些简单的加密/解密函数。这将是一个内部网页,因此用户将被隐式信任。有没有办法做到这一点?我将需要击中用户的Windows-MY密钥存储区(通过CAPI)以提取解密密钥,并且击中LDAP服务器以获取用于加密的公钥。嵌入.Net C#在网页?

回答

1

我最终用C#伪造了一个COM对象,然后使用JavaScript调用该COM对象,并且能够通过浏览器与CAPI进行交互。

的JavaScript:

<html> 
<head> 
<script language="javascript"> 
var keystore = new ActiveXObject("RBCrypto.KeyStore"); 

function getCertList() 
{ 
    try { 
    keystore.openKeyStore("MY", true, false); 
    var size = keystore.getStoreSize(); 

    var list = document.getElementById('list'); 
    list.size = size; 

    for(var i = 0; i < size; i++) 
    { 
     var fname = keystore.getFriendlyName(i, true); 
     var opt = new Option(fname, fname); 
     list.options.add(opt); 
    } 
    } 
    catch(err) 
    { 
    alert(err.description); 
    } 
} 
</script> 
</head> 
<body onload="getCertList()"> 
    <center> 
    <h2>KeyStore Test</h2> 
    <hr /> 
    <br /> 
    <select id="list"></select> 
    </center> 
</body> 
</html> 

C#:

using System; 
using System.Runtime.InteropServices; 
using System.Security; 
using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 

namespace RBCrypto 
{ 
    public interface AXInterface 
    { 
     void openKeyStore(string storeName, bool currentUser, bool readOnly); 
     int getStoreSize(); 
     string getFriendlyName(int index, bool subjectNameIfEmpty); 
    } 

    [ClassInterface(ClassInterfaceType.AutoDual)] 
    public class KeyStore :AXInterface 
    { 
     public void openKeyStore(string storeName, bool currentUser, bool readOnly) 
     { 
      if (keystoreInitialized) 
       throw new Exception("Key Store must be closed before re-initialization"); 

      try 
      { 
       if (currentUser) //user wants to open store used by the current user 
        certificateStore = new X509Store(storeName, StoreLocation.CurrentUser); 
       else    //user wants to open store used by local machine 
        certificateStore = new X509Store(storeName, StoreLocation.LocalMachine); 

       if (readOnly) 
        certificateStore.Open(OpenFlags.ReadOnly); 
       else 
        certificateStore.Open(OpenFlags.ReadWrite); 

       allCertificates = certificateStore.Certificates; 

       if (allCertificates == null) 
       { 
        certificateStore.Close(); 
        throw new NullReferenceException("Certificates could not be gathered"); 
       } 

       keystoreInitialized = true; 
      } 
      catch (ArgumentException ae) 
      { 
       throw ae; 
      } 
      catch (SecurityException se) 
      { 
       throw se; 
      } 
      catch (CryptographicException ce) 
      { 
       throw ce; 
      } 
      catch (NullReferenceException ne) 
      { 
       throw ne; 
      } 
     } 

     .... 
    } 
} 

C#程序集信息:

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components. If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type. 
[assembly: ComVisible(true)] 

为了这个工作,用户必须6.在安装他们的机器上您的.dll(确保你指定在您的安装程序中将.dll注册为vsdraCOM),并且他们必须将您的网站添加到他们的truste d站点。

4

您可以使用Silverlight。

但是请注意,你可以在Javascript中做加密,以及:

+0

我想使用已存在于用户的Windows-MY密钥存储区中的密钥,以及从哪里读取Siverlight和Javascript都不能访问它们 – 2010-07-19 19:07:18

+0

@Petey:那么您需要编写一个浏览器插件。 – SLaks 2010-07-19 19:42:40

+0

感谢SLaks(这应该是Ex Lax上的游戏?),我应该从哪里开始寻找关于浏览器插件的信息? – 2010-07-19 19:56:30

4

定义“进入网页”的含义?网页由浏览器运行,通常只有Javascript(和Java)。

您可以将它作为Silverlight应用程序来执行。

+0

Silverlight没有我需要的加密功能。除非有办法击中我发现的Windows-MY密钥库? – 2010-07-19 19:10:35

1

考虑编写一个新的ASP.NET应用程序,其中加密/解密逻辑位于应用程序中。也许创建一个新的webforms应用程序,其中有一个专门用于填充这些请求的页面。

考虑在单独的.NET程序集中编写加密逻辑,然后从ASP.NET应用程序中引用该程序集。

目前尚不清楚您是否希望将其作为服务,或者用户是否希望在文本框中输入文本,并让它在访问时执行加密。

+0

这将工作,但我需要一种方法来从他们的Windows-MY密钥库中获取用户的私钥以解密。其他一切都可以在服务器端完成。 – 2010-07-19 19:13:52

0

您可以使用AJAX并调用您在网络上使用的加密函数。