Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/252.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中使用纯文本作为键和IV';s mcrypt_Php_Encryption_Mcrypt_Tripledes - Fatal编程技术网

在PHP中使用纯文本作为键和IV';s mcrypt

在PHP中使用纯文本作为键和IV';s mcrypt,php,encryption,mcrypt,tripledes,Php,Encryption,Mcrypt,Tripledes,我有一个应用程序,它使用CBC方法在商定的密钥和IV上以三重加密方式在供应商的应用程序之间交换数据。我的应用程序是VB.NET应用程序,而供应商的应用程序是PHP网页。奇怪的是,我似乎无法匹配供应商应用程序的输出 密钥和初始向量以明文形式提供给我们两人。有趣的是,在供应商的应用程序中,他们不会散列或将密钥和IV转换为256位密钥和128位IV。他们只是使用PHP中的mcrypt插件在代码中使用明文格式 $key = 'plaintextkey'; $iv = 'plaintextIV' $enc

我有一个应用程序,它使用CBC方法在商定的密钥和IV上以三重加密方式在供应商的应用程序之间交换数据。我的应用程序是VB.NET应用程序,而供应商的应用程序是PHP网页。奇怪的是,我似乎无法匹配供应商应用程序的输出

密钥和初始向量以明文形式提供给我们两人。有趣的是,在供应商的应用程序中,他们不会散列或将密钥和IV转换为256位密钥和128位IV。他们只是使用PHP中的mcrypt插件在代码中使用明文格式

$key = 'plaintextkey';
$iv = 'plaintextIV'
$enc = mcrypt_encrypt(MCRYPT_3DES, $key, $string, MCRYPT_MODE_CBC, $iv)
它产生了一个有趣的文本,比如:

û!‰+«°z0"üÐÑn û!‰+«z0»Ðñn 我的问题是:

  • 如果使用纯文本作为参数,PHP如何 实现/转换为256位字符
  • 如果使用CBC方法,它不应该依赖于以前的方法吗 加密文本
  • 在我给定的格式中有三倍的结果吗?因为 通过互联网搜索,我从来没有看到过结果 这种形式的加密
  • 如果将明文用作参数,PHP如何实现/将其转换为256位字符

    三重DES是三次使用三个(不同)DES密钥的DES和应用。一个DES密钥长度为56位,奇偶校验为64位。因此,一个3DES密钥应该由三个不同的DES密钥组成,这将产生一个192位密钥

    密钥应该具有高熵,因此有必要强制使用相当大的密钥空间。如果密钥是密码,那么这将非常容易,因为密码具有固有的格式和有限的字符集。这就是为什么密钥需要从密码派生。这通常通过PBKDF2、bcrypt o来完成r scrypt(随机生成的salt和大量数千或数百万次的迭代/高成本因素)

    现在,mcrypt做出了一些有问题的决定。例如,它乐于接受(在早期的PHP版本中)无效的密钥和IVs,将0x00字节填充到下一个有效大小,或将它们裁剪到下一个有效大小。这就是为什么使用“plaintextkey”“这不是个好主意。它将导致第二个密钥的某些字节为0x00字节,第三个密钥的完整0x00字节

    mcrypt是弃用软件,不应再使用。您可以在PHP中使用OpenSSL扩展,也可以使用许多优秀的加密库,如libnaude或defuse/PHP encryption

    如果使用CBC方法,它不应该依赖于先前加密的文本吗

    您可以使用最后一个密文块作为下一次加密的IV,但这只会使加密代码复杂化。你真的应该每次都使用一个随机的IV,并简单地在它前面加上密文。这不一定是秘密,而是不可预测的。你们可以把它和以前的盐放在一起。另见:

    在我给定的格式中是否有三重结果?因为当我在互联网上搜索时,我从来没有见过这样的加密结果


    现代密码(保留格式的加密是一个显著的例外)产生的密文应该是安全的。因此,作为密文的一部分,您可能会收到\x01等不可打印字符。要打印密文,则需要使用十六进制或Base 64编码为可打印格式。

    多亏Artjom的回答提到,需要添加几个0,直到密钥和IV分别达到24和8的长度。下面是VB.NET代码,以防有人需要

    Dim byteKey As Byte() = System.Text.Encoding.UTF8.GetBytes("myplaintextkey")
    Dim byteVector As Byte() = System.Text.Encoding.UTF8.GetBytes("myplaintextiv")
    
    Dim base64Key As String = Convert.ToBase64String(byteKey)
    Dim base64Vector As String = Convert.ToBase64String(byteVector)
    
    Dim key As Byte() = Convert.FromBase64String(base64Key)
    Dim iv As Byte() = Convert.FromBase64String(base64Vector)
    
    Dim encryptor As SymmetricEncryptor = New SymmetricEncryptor() 'Note, this an internal library
    
    Try
        encryptor.Provider = New System.Security.Cryptography.TripleDESCryptoServiceProvider
    
        encryptor.Encoder = System.Text.Encoding.UTF8
        encryptor.Provider.Mode = CipherMode.CBC
        encryptor.Provider.Padding = PaddingMode.Zeros
    
        'Add missing zeros to key and IV
        If key.Length < 24 Then
            Dim i As Integer = key.Length
            ReDim Preserve key(23)
            While i < 24
                key(i) = 0
                i += 1
            End While
        ElseIf key.Length > 24 Then
            ReDim Preserve key(23)
        End If
    
        If iv.Length < 8 Then
            Dim i As Integer = iv.Length
            ReDim Preserve iv(8)
            While i < 8
                iv(i) = 0
                i += 1
            End While
        ElseIf iv.Length > 8 Then
            ReDim Preserve iv(8)
        End If
        encryptor.IV = iv
        encryptor.Key = key
    
        Dim output As String = encryptor.Encrypt(output)
    
        Console.Write(output)
    Catch ex As Exception
        Console.Write(ex.Message)
    End Try
    
    Dim byteKey As Byte()=System.Text.Encoding.UTF8.GetBytes(“myplaintextkey”)
    Dim byteVector As Byte()=System.Text.Encoding.UTF8.GetBytes(“myplaintextiv”)
    Dim base64Key As String=Convert.ToBase64String(byteKey)
    Dim base64Vector As String=Convert.ToBase64String(字节向量)
    Dim key As Byte()=Convert.FromBase64String(base64Key)
    Dim iv As Byte()=Convert.FromBase64String(base64Vector)
    Dim encryptor As SymmetricEncryptor=新SymmetricEncryptor()'注意,这是一个内部库
    尝试
    encryptor.Provider=新System.Security.Cryptography.TripleDESCryptoServiceProvider
    encryptor.Encoder=System.Text.Encoding.UTF8
    encryptor.Provider.Mode=CipherMode.CBC
    encryptor.Provider.Padding=PaddingMode.Zeros
    '将缺少的零添加到键和IV
    如果键长<24,则
    尺寸i为整数=键长度
    重拨保留键(23)
    而我<24岁
    键(i)=0
    i+=1
    结束时
    ElseIf键。那么长度>24
    重拨保留键(23)
    如果结束
    如果iv.长度小于8,则
    尺寸i为整数=尺寸iv.长度
    雷迪姆保护区四(8)
    当我<8
    iv(i)=0
    i+=1
    结束时
    ElseIf iv.长度>8那么
    雷迪姆保护区四(8)
    如果结束
    加密机IV=IV
    encryptor.Key=密钥
    Dim输出为字符串=encryptor.Encrypt(输出)
    控制台写入(输出)
    特例
    控制台写入(例如消息)
    结束尝试
    

    我希望它能帮助别人,再次感谢你,Artjom

    那么我想他们采取了一种相当简单的方法。试着把他们指向它所建议的正确的做事方式,不管是在一个例子中,还是在对mcrypt的描述中functions@RiggsFolly那么,他们使用钥匙和IV是错误的?我看到,在以前的PHP版本中,他们添加了\0填充,以前的键和IVs填充了“\0”字节,以达到下一个有效大小。因此,如果他们使用的是最新的PHP,它将返回false?哇,这真的很有帮助。简而言之,为了匹配供应商的输出,我必须在键和向量中添加一些零填充,对吗?我想告诉他们mcrypt已经过时了,但我不认为这是我该说的(是的,用0x00字节填充最多24字节的键,并在前8个字节剪切IV应该可以。请记住,mcrypt使用零填充