【问题标题】:How can I implement strong, reversible encryption that inter-operates between ASP.NET 2.0, Coldfusion 5, and Classic ASP?如何实现在 ASP.NET 2.0、Coldfusion 5 和 Classic ASP 之间互操作的强大、可逆的加密?
【发布时间】:2012-01-29 12:30:46
【问题描述】:

我的组织已决定对我们数据库中的某些数据进行加密,我被赋予了实施加密的任务。我需要能够加密数据,将加密版本存储在我们数据库的 VARCHAR 字段中,然后检索它并将其解密回正常状态。

从表面上看,这似乎是一项简单的任务。有多种方法可以实现加密。我之前使用过的一种是基于this StackOverflow question 中的 AES 加密代码。

在这种情况下更难的是,我需要编写代码来加密/解密访问我们数据库的各种应用程序中的数据,其中一些应用程序是使用不同的技术开发的。我们有使用 Coldfusion 5、Classic ASP 和 ASP.NET 2.0 编写的应用程序。我需要能够使用 Coldfusion 代码加密数据并将其存储在数据库中,然后在 ASP.NET 中将其读取并解密回其原始形式。或者在 Classic ASP 中加密它并在 Coldfusion 中解密。或这些平台的任何其他组合。

事实证明,这比我预期的要难。即使给定相同的数据和相同的共享密钥,声称使用相同算法的不同类/对象/函数/库似乎也会产生不同的结果。过去,我们使用 CAPICOM 在 Coldfusion 和 Classic ASP 之间提供加密互操作性。但是我在尝试让它在 ASP.NET 中工作时遇到了麻烦。我读过this article about how to get CAPICOM to work in .NET,但这些建议对我没有用。我什至无法生成互操作类或导入对 COM 对象的引用而不会出错。此外,我们的一些生产服务器的操作系统似乎与 CAPICOM 不兼容,因此无论如何这可能是一条死胡同。

对于我如何实现加密,让 3 个平台中的任何一个都可以解密其他平台加密的内容,同时仍然使用相当强大的算法,是否有人有任何建议?

2011-12-29 编辑:

正如下面的 cmets 所述,我目前希望找到一个 ASP.NET 解决方案,它与我们现有的一些使用 CAPICOM 的 Coldfusion/ASP Classic 代码兼容。这样做的原因是,我们的团队负责人不希望我为我们当前的目的在我们的代码中引入一种新的加密方法,除非我还修改了使用加密的旧应用程序以用于不同的目的以使用相同的方法。他想为这两个目的使用相同的加密方法。由于修改我们的旧应用程序以使用新的加密方法不仅意味着更改代码,还意味着跟踪旧应用程序加密的所有数据,解密并使用新方法重新加密,所以我犹豫不决除非我必须这样做,否则这条路线。希望我能找到一种方法让 ASP.NET 读取现有的加密数据。

来自我们其他 Coldfusion 和 ASP Classic 应用程序的加密数据是使用 CAPICOM COM 对象编码的。据我所知,这些设置普遍是 AES 加密、最大密钥大小(我相信在 AES 中是 256 位)。

应@Leigh 的要求,以下是我们现有的 CF 应用程序如何使用 CAPICOM 的简化示例:

<cfscript>
    encryptObject = CreateObject("com","CAPICOM.EncryptedData");
    encryptObject.Algorithm.Name = 4; // 4 is AES
    encryptObject.Algorithm.KeyLength = 0; // 0 is MAX, I believe 256-bit in the case of AES
    encryptObject.SetSecret(sharedSecret);
    encryptObject.Content = stringToEncrypt;

    encryptedData = localScope.encryptObject.Encrypt();
</cfscript>

【问题讨论】:

  • 请注意您的标签选择。 asp 标签被证明是模棱两可的,并被清理以支持asp-classic。您在 Stack Overflow 上的唯一问题会被标记为 asp,这应该会引起很大的危险。
  • @Joel 我很抱歉。没注意,以后会仔细看的。
  • 您使用的是什么数据库产品?
  • @Joshua - 哦,我没有意识到你使用的是 CF 的 CAPICOM,而不是内置的加密函数。根据我所读到的,CAPICOM 的做法与此断开的链接中描述的有所不同:jensign.com/JavaScience/dotnet/DeriveBytes。您可以使用wayback machine 查看它。您对互操作程序集有什么问题,因为这似乎是最简单的方法?

标签: asp.net encryption asp-classic coldfusion


【解决方案1】:

由于您在所有系统之间拥有通用数据库平台,因此我会将您的加密/解密留在那里。这是一篇关于 SQL 2005 中特定于列的加密的文章:

http://msdn.microsoft.com/en-us/library/ms179331(v=sql.90).aspx

【讨论】:

  • 谢谢!这是一个中肯的建议。我不知道这是一个选择。我将由团队运行它,看看是否有人对此有问题。
  • 只是不要将密钥存储在数据库中。
  • 这是个好建议。我由项目负责人运行它,他说他同意我使用它如果我修改了我们所有现有的加密/解密代码,也都是基于 SQL 的,因此我们的方法是一致的。啊。这仍然在桌面上,但如果我能找到与我们过去在 CF 和经典 ASP 中使用的 CAPICOM 方法配合得很好的 ASP.NET 代码,那么工作量就会减少。所以我现在要继续努力。
  • 我意识到我的问题与我最初提出的问题有所不同。我最喜欢这个答案,我认为这是我最初描述的问题的一个很好的解决方案,所以我接受它。谢谢!
【解决方案2】:

我刚刚做了类似的事情(在 Classic ASP 和 ASP .NET 之间进行加密,忽略 Coldfusion),我也遇到过 CAPICOM 几次,但经过多次来回(和搜索)后,我发现了一个 COM AES/Rijndael我最终使用的库,Hyeongryeol.Security.Cryptography(由于某种原因,下载名为 .wma - 它是一个 zip 文件,因此请使用 7-Zip 或您使用的任何工具手动打开它)。

.NET 中的加密/解密使用RijndaelManaged 类(下载中有一个示例)。

总而言之,开始工作非常简单。只需注册 COM DLL(适用于 Classic ASP)就可以了。这是我们的 build.bat 的摘录,它确保(希望)它已注册:

echo Registering HyeongryeolStringEncrypter.dll
copy Libraries\Hyeongryeol.Security.Cryptography\ASP\HyeongryeolStringEncrypter.dll %system32%\HyeongryeolStringEncrypter.dll
regsvr32 /s %system32%\HyeongryeolStringEncrypter.dll

只要确保两边使用相同的密钥/IV。

【讨论】:

  • 我知道RijndaelManaged 类,但我不知道如何让它与我在 ASP 和 CF 中可用的密码学功能相得益彰。例如,我不明白的一件事——在我们现有的 ASP 经典代码中,当我们使用 CAPICOM 加密时,我们只需要设置数据、加密方法和密钥。但是 RijndaelManaged 类的CreateEncryptor 函数需要一个键和一个向量。什么是向量,为什么 CAPICOM 不需要它,我可以将什么传递给 CreateEncryptor 会产生与 CAPICOM 相同的结果?
  • 如果您使用 Hyeongryeol COM DLL,则无需使用 CAPICOM。 Hyeongryeol 接受密钥/IV 参数(与 RijndaelManaged 相同),在我的所有测试中,我都能够在 ASP 或 ASP .NET 端成功加密/解密字符串并获得相同的结果。
  • 明白。不幸的是,我们已经有一些使用 CAPICOM 的应用程序,如果这个项目的解决方案是兼容的,那就太理想了。我将首先尝试找到一种与我们现有的 CAPICOM 代码兼容的 ASP.NET 解密方法。如果找不到,我会研究 Hyeongryeol 或基于 SQL Server 的加密。
  • @Joshua - Re:什么是向量,为什么 CAPICOM 不需要它 RijndaelManaged 默认使用 CBC 模式,这需要 iv。也许 CAPICOM 使用了不需要 iv 的不太安全的 EBC 模式(如 CF)。
【解决方案3】:

加密只是修改您的数据,使其不可读,然后使用与原始公式相反的方法将其修改回来。

我个人会坚持使用 AES,您应该能够为这些平台获取 AES。

根据你希望它有多强大,你可以写一个简单的函数来自己做。

可以像根据某个键向信息中添加一系列位一样简单。

【讨论】:

    【解决方案4】:

    在对多个网站进行广泛搜索后,其他人建议使用 SSO,但显然存在局限性,我找到了下面的代码,它可以满足我的需求。

    1. 我们有一个现有的 CF 站点,我们正在使用 ASP.NET 和 Membership 提供程序对其进行重新设计。
    2. 我们希望保留现有 CF 中的密码,但将其传输到 aspnet_membership 表,并对它们进行哈希处理。
    3. 我们还希望能够从任一系统更改密码,因为它们最多可以同时运行 3 个月。
    4. 这意味着我们希望能够从 CF 更新 aspnet_membership 表并针对该表进行身份验证。

    下面的代码允许我们对来自 CF 的密码进行哈希处理,并将其与 aspnet_membership 表进行匹配。如果Based64Hash与表中的密码相同,则可以对用户进行身份验证。如果用户想从 CF 端更改密码,我们现在可以加密密码,并且仍然在 ASP.NET 端进行验证。

    更新修复了串联问题

    <cfscript>
        thePassword = "originalPassword";
        base64Salt = "JZjdzUXREM0A7DPI3FV3iQ==";
    
        // extract bytes of the salt and password
        saltBytes = binaryDecode(base64Salt, "base64");
        passBytes = charsetDecode(thePassword, "UTF-16LE" );
    
        // next combine the bytes. note, the returned arrays are immutable, 
        // so we cannot use the standard CF tricks to merge them    
        ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
        dataBytes = ArrayUtils.addAll( saltBytes, passBytes );
    
        // hash binary using java
        MessageDigest = createObject("java", "java.security.MessageDigest").getInstance("SHA-1");
        MessageDigest.update(dataBytes);    
        theBase64Hash = binaryEncode(MessageDigest.digest(), "base64");
    
        WriteOutput("<br />theBase64Hash= "& theBase64Hash &"<br/>");
    </cfscript>
    

    【讨论】:

    • 如果可能,您应该切换到更安全的算法。 CFMX_COMPAT 非常弱,只是为了向后兼容而包含在内。
    • 感谢@Leigh 提供示例代码。它真的对我们有用。我们必须使用 SHA1 哈希的原因是由于 ASP.NET 成员控制。
    • 是的,代码有效。这不是很安全。因此建议切换到更强大的算法;-)
    • 仅供参考,更新了代码示例以解析an issue with certain values when concatenated
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 2010-11-18
    • 2016-03-09
    • 1970-01-01
    相关资源
    最近更新 更多