C# 和 PHP 上的三重 DES 加密会产生不同的结果

2024-02-08

我正在编写一个简单的登录加密系统,但有一个小问题。 C# 加密函数:

public static string EncryptString(string Message, string Passphrase)
{
    byte[] Results;
    System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

    // Step 1. We hash the passphrase using MD5
    // We use the MD5 hash generator as the result is a 128 bit byte array
    // which is a valid length for the TripleDES encoder we use below

    MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
    byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

    // Step 2. Create a new TripleDESCryptoServiceProvider object
    TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

    // Step 3. Setup the encoder
    TDESAlgorithm.Key = TDESKey;
    TDESAlgorithm.Mode = CipherMode.ECB;
    TDESAlgorithm.Padding = PaddingMode.PKCS7;

    // Step 4. Convert the input string to a byte[]
    byte[] DataToEncrypt = UTF8.GetBytes(Message);

    // Step 5. Attempt to encrypt the string
    try
    {
        ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
        Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
    }
    finally
    {
        // Clear the TripleDes and Hashprovider services of any sensitive information
        TDESAlgorithm.Clear();
        HashProvider.Clear();
    }

    // Step 6. Return the encrypted string as a base64 encoded string
    return Convert.ToBase64String(Results);
}

EncryptString("test", "123456")回报"Yjaqhc7RFds=".

php 中的相同代码:

  <?php
    $key = "123456";
    function pkcs7_pad($text, $blocksize)
    {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    $input = pkcs7_pad("test", 16);
    $key = md5(utf8_encode($key), true);
    $td = mcrypt_module_open('tripledes', '', 'ecb', '');
    $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $key, $iv);
    $encrypted_data = mcrypt_generic($td, $input);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);

    echo base64_encode($encrypted_data);
?>

returns "dybhiZYdKG8pNCgCFkbV6g=="?我究竟做错了什么?


您遇到此问题是因为 Triple DES 的密钥大小为 168 位(21 字节),但 MD5 生成的哈希值只有 16 字节(128 位)长。

这意味着密钥必须扩展到 168 位,以便 Triple DES 可以工作。事实证明,这种从 128 位到 168 位的推导在 C# 中的工作方式与在 PHP 中的工作方式不同,因此有效使用的密钥不同,从而产生不同的加密数据。

现在你有两个选择:


选项 1:选择完全支持 128 位密钥的密码

如果您使用支持 128 位密钥的密码,则可以避免与密钥大小差异相关的所有问题。这将需要对您的代码进行最少的更改。例如,您可以使用 Rijndael (AES)。

C#: 改变TripleDESCryptoServiceProvider to RijndaelManaged.
其他一切都可以保持不变。(Demo) http://ideone.com/huPErj

PHP: Use MCRYPT_RIJNDAEL_128而不是三元组(Demo) http://ideone.com/TEU3zr:

function encrypt_pkcs7($str, $key)
{
    $key = md5(utf8_encode($key), true);
    $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $pad = $block - (strlen($str) % $block);
    $str .= str_repeat(chr($pad), $pad);

    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
    return base64_encode($ciphertext);
}

echo encrypt_pkcs7('test', '123456');

请注意,AES 的有效密钥大小大于 Triple DES。虽然 Triple DES 的密钥是 168 位长,但它只提供 112 位的安全性。如果我是你,我会选择这个选项。


选项 2:使用 192 位密钥而不是 128 位密钥

如果您使用的密钥比 Triple DES 实际使用的密钥大,C# 和 PHP 似乎就如何将其减少到 168 位达成了一致。您可以使用 SHA-256 等哈希函数来实现此目的,该函数生成 256 位哈希并将其修剪为 192 位(24 字节):

C#: Use SHA256CryptoServiceProvider and Array.Copy获取 192 位密钥,并将其与程序的其余部分一起使用:(Demo) http://ideone.com/emTLD9

SHA256CryptoServiceProvider HashProvider = new SHA256CryptoServiceProvider();
byte[] temp = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
byte[] key = new byte[24];
Array.Copy(temp, key, 24);

PHP: Use hash()使用 SHA-256 和substr()获取192位密钥

function encrypt_pkcs7($str, $key)
{
    // derive 192-bit key using SHA-256
    $key = substr(hash('sha256', $key, true), 0, 24);
    $block = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_ECB);
    $pad = $block - (strlen($str) % $block);
    $str .= str_repeat(chr($pad), $pad);

    $ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $str, MCRYPT_MODE_ECB);
    return base64_encode($ciphertext);
}

echo encrypt_pkcs7('test', '123456');

我似乎无法提供 168 位密钥TripleDESCryptoServiceProvider,我不知道为什么。


其他考虑因素:

  • 考虑使用 SSL;即使它是自签名证书。它胜过重新发明轮子,当涉及密码学时,这是一项特别危险的任务。

  • 考虑使用 ECB 以外的操作模式(例如:CBC)。使用 ECB 会增加安全风险。阅读维基百科关于分组密码操作模式的文章 http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation.

  • 除非你绝对地需要有一个明文密码(很少有这种情况),您应该对密码进行哈希处理。读这篇关于保护密码的文章。 http://crackstation.net/hashing-security.htm

  • 考虑使用适当的基于密码的密钥派生函数,例如PBKDF2 http://en.wikipedia.org/wiki/PBKDF2而不是 MD5 或 SHA 系列等通用哈希函数。这将使破解密钥变得更加困难。有关更多信息,请阅读上一个要点中的文章。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 和 PHP 上的三重 DES 加密会产生不同的结果 的相关文章

  • C# 动态 Linq 变量Where 子句

    我正在按照 Scott Gu 的文章创建动态 LINQhttp weblogs asp net scottgu archive 2008 01 07 dynamic linq part 1 using the linq dynamic qu
  • 堆栈独立的C/C++蓝牙API?

    我想知道是否有适用于 Windows XP Vista 7 x86 和 x64 的堆栈独立 C C 蓝牙 api 我的目标是创建连接并通过蓝牙发送 接收一些时间关键的数据 我的研究给了我以下选择以及这项任务的缺点 用于蓝牙的 Windows
  • Doctrine QueryBuilder 重用部件

    我想计算所有符合我的条件的字段 并使用学说查询生成器逐页获取它们 我生成的查询取决于我的过滤器字段 第一部分是计算记录 以便我可以计算页数 qb em gt createQueryBuilder qb gt select COUNT m i
  • 模拟 EF core dbcontext 和 dbset

    我正在使用 ASP NET Core 2 2 EF Core 和 MOQ 当我运行测试时 我收到此错误 消息 System NotSupportedException 非虚拟 可在 VB 中重写 成员上的设置无效 x gt x Movies
  • empty() 在对象的非空属性上返回 TRUE

    我遇到了一个非常奇怪且意想不到的问题 empty 正在返回TRUE由于我不知道的原因 在一处非空的房产上 class MyObject private property public function construct property
  • 如何在Qt无框窗口中实现QSizeGrip?

    如何使用 Qt 无框窗口实现 QSizeGrip 代码会是什么样的 您只需在布局内窗口的一角添加 QSizeGrip 即可使其保持在该角落 QDialog dialog new QDialog 0 Qt FramelessWindowHin
  • 接口中的私有成员

    是否可以在 NET 接口中创建私有成员 我听说现在可以了 但我的 IDE 拒绝了 public interface IAnimal void SetDefaultName string name ChangeName name privat
  • 如何使用 python-gnupg 加密大型数据集而不占用所有内存?

    我的磁盘上有一个非常大的文本文件 假设它是 1 GB 或更多 还假设该文件中的数据有 n每 120 个字符一个字符 我在用python gnupg https pythonhosted org python gnupg 对此文件进行加密 由
  • 从 Linq 的列表中选择多个字段

    在 ASP NET C 中 我有一个结构 public struct Data public int item1 public int item2 public int category id public string category
  • CS0246 找不到类型或命名空间名称“ErrorViewModel”(您是否缺少 using 指令或程序集引用?)

    我收到 CS0246 错误代码 我正在做一个 MVC net core 项目 我正在将 Razor 合并到我的 C 代码中 我在进行构建时收到此错误 我在最后一行收到错误 有人能帮我解决这个问题吗 global Microsoft AspN
  • 如何定义 Swagger UI 参数的默认值?

    我已将 Swagger Swashbuckle 集成到 NET Core 2 2 API 项目中 一切都很好 我的要求纯粹是为了方便 考虑以下 API 方法 public Model SomeEstimate SomeRequest req
  • 当“多次安装 MSBuild”时,Dotnet 项目转换尝试转换失败

    try convert w Test csproj target framework netstandard2 0 结果是 Multiple installs of MSBuild detected please select one In
  • Cuda:最小二乘求解,速度较差

    最近 我使用Cuda编写了一个名为 正交匹配追踪 的算法 在我丑陋的 Cuda 代码中 整个迭代需要 60 秒 而 Eigen lib 只需 3 秒 在我的代码中 矩阵 A 是 640 1024 y 是 640 1 在每一步中 我从 A 中
  • 更改预处理到文件后出现错误 1 ​​错误 LNK1104

    我必须使用预处理器 所以我改变了 配置属性 gt C gt 预处理器 gt 预处理为文件 gt 是 并得到错误 错误 1 错误 LNK1104 无法打开文件 Debug asnreal obj 这个问题的解决办法 我必须在 lib 文件的路
  • Drupal 模板/主题资源或建议?

    我有兴趣为我正在开发的 Drupal 网站创建自定义主题 我是 Drupal 的新手 但是我在处理构建主题 CSS PHP HTML 所需的基本概念方面拥有相当多的经验 所以 我的问题是 我从哪里开始 有创建 Drupal 主题的规范指南吗
  • 如何使用多个分隔符拆分列表?

    基本上 我想在文本区域中输入文本 然后使用它们 例如 variable1 variable2 variable3 variable1 variable2 variable3 variable1 variable2 variable3 我知道
  • 访问 Visual Studio 扩展中的当前代码窗格

    我正在编写一个 Visual Studio 2010 扩展 在代码视图中带有右键单击菜单 我希望能够从菜单项事件处理程序检查当前代码 但无法在对象模型中找到执行此操作的位置 如何在 Visual Studio 扩展中访问当前窗口中的代码 E
  • Android NDK - 仅用 C/C++ 编写

    有没有一种可能的方法可以使用 C C 编写整个 NDK 应用程序 而无需像 hello jni 示例项目 HelloJni java 中那样的 Java 入门 类 以某种方式创建一个 HelloJni c 来执行相同的操作 从 Androi
  • 将文件附加到 PHPMailer

    我目前正在开发一个项目 该项目将文件作为 blob 存储在数据库中 我需要将文件附加到电子邮件并通过 PHPMailer 发送出去 我熟悉 mail gt addAttachment 但是 这个函数似乎只接受文件路径 而我没有 我想知道是否
  • File_get_contents($url): 无法打开流

    我有一个脚本 我使用以下方法读取文件 file get contents urlencode url 我收到此错误 failed to open stream HTTP request failed HTTP 1 0 400 Bad req

随机推荐

  • SSD 驱动器会让 Maven 构建更快吗?

    好帖子在这里 https stackoverflow com questions 4557934 would a ssd vs fast hdd drive make my eclipse run compile faster据说使用 SS
  • 如何使用公共函数从 Bytes 返回 KB、MB 和 GB

    我正在编写一个返回文件大小 以 B KB MB GB 为单位 的 函数 VB Net 代码总是首先获取以字节为单位的大小 因此当文件的大小 以字节为单位 小于 100 时 它返回 B 如果它 gt 1000 则将其除以 1000 然后返回
  • EJB 3.1 |通过 JNDI 调用远程会话 bean 时出错

    我试图从 Java SE 简单类 调用一个简单的无状态会话 bean 这是我的豆子 import javax ejb Stateless author MMRUser Stateless public class CapitalBean i
  • Android 11 5G 获取小区参数

    我正在新的 Android studio 预览版上尝试网络类型 5G 上的 Android 11 我的目标是获取单元信息详细信息 但是 方法 getAllCellInfo 在模拟器上返回空 空列表 Android 11 之前的所有模拟器都会
  • Android 在可扩展列表视图中禁用自动滚动

    我在可扩展列表视图中使用 当我打开列表视图中的某个项目时 我的滚动会自动聚焦在打开的项目上 我可以阻止列表聚焦在新项目上并停留在同一个地方吗 我尝试从打开的视图中删除可聚焦的内容 但它不起作用 您需要重写 OnGroupClickListe
  • 无法从 EC2 实例元数据服务检索凭证

    我正在尝试使用 SDK 通过 AWS SES API 发送电子邮件 我的代码基于此处的官方文档 https docs aws amazon com ses latest DeveloperGuide examples send using
  • 最少使用的 unicode 分隔符

    我正在尝试在特定位置使用分隔符标记我的文本 稍后将使用该分隔符进行解析 我想使用最不常用的分隔符 我当前正在查看 2 或 U 0002 字符 使用起来足够安全吗 还有哪些其他建议 文本为 unicode 同时包含英语和非英语字符 A想要使用
  • 字体真棒图标在 Chrome 中显示为正方形?

    我正在尝试在按钮中使用字体很棒的图标 该图标在 Firefox 中工作正常 但当我在 Chrome 中使用它时 它显示为正方形 我环顾四周 唯一发现的是字体的路径可能不正确 但我后来尝试了 cdn 版本here http www boots
  • PacMan:主要使用哪些启发式方法?

    除了 A BFS DFS 等之外 Pacman 中还广泛使用其他哪些好的寻路算法 启发式算法 如果吃豆人可以找到不止一种水果 我认为我提到的那些不会起作用 我需要一些好的寻路算法 PacMan 可以使用它们以尽可能少的步数完成迷宫 我试图四
  • 接口上的属性有什么用?

    使用 Resharper 我提取了现有类的接口 这个类在一些成员上设置了一些属性 Resharper 也将这些属性放在接口成员上 我可以从界面中删除这些属性吗 实现接口时不会继承接口上的属性 对吧 它们不被实现类使用 但仍然可能很关键 例如
  • 反应路由器索引路由始终处于活动状态

    我正在尝试使用 React 来设计我的导航activeClassName属性 到目前为止 它按预期工作 但有一个问题 我的第一个导航链接指向根路线 因此 即使在另一个 URL 上 它也会将该 URL 例如 skills 和 root 注册为
  • JQUERY UI - 根据验证选择选项卡

    我将 Jquery UI 选项卡式表单与需要验证的每个选项卡上的输入放在一起 理想情况下 我想验证当前可见的选项卡 然后选择下一个不验证的选项卡 最好的方法是什么 我的代码如下 div ul li a href tab1 One a li
  • 发送带有源端口但不绑定的 UDP 数据包

    我想在 Python 中发送 UDP 数据包并指定源端口但不绑定 与 hping3 等效 hping3 s sourceport p remoteport udp file message bin d 1024 c 1 remoteaddr
  • Googletest Eclipse C++:如何同时具有测试和生产可执行文件?

    我有一个基本问题谷歌测试 https code google com p googletest 在 Eclipse 中 我正在使用测试运行者 https github com xgsa cdt tests runner wiki Tutor
  • 在控制台中访问新的 ember 路由器

    是否有等效的函数可以使用 ember 中的新路由器在控制台中获取 currentPath 之前 我能够做到这一点 App router get currentPath 但是 似乎使用新路由器 您无法以相同的方式访问路由器 事实上 App r
  • 使用 OpenSSL 将现有 TCP 套接字转换为 TLS

    我需要一些有关 OpenSSL TLS 套接字的信息 首先 我想通过 TCP 上的 TLS 与服务器建立连接 通常首先创建一个 TCP 套接字 然后使用 TCP 套接字连接到服务器 然后将 TCP 套接字转换为 TLS 在通过 TCP 套接
  • 根据父高度调整 Imageview 的大小

    我有一个如下定义的布局
  • 如何为 iPhone 创建自定义弹出窗口?

    I want to create a custom popup window for iPhone which should look like this 对于 iPhone 和 iPod 设备来说 最正确的实现方法是什么 执行此操作的最佳
  • 在图库中找不到图像

    我需要测试一个需要从 Android JellyBean 模拟器图库中选取一些图像的功能 所以我使用模拟器自己的浏览器 速度太慢了 从互联网上下载了一些图像 图像出现在下载的文件中 但不出现在模拟器图库中 在 GingerBread 模拟器
  • C# 和 PHP 上的三重 DES 加密会产生不同的结果

    我正在编写一个简单的登录加密系统 但有一个小问题 C 加密函数 public static string EncryptString string Message string Passphrase byte Results System