在Python中复制Java的PBEWithMD5AndDES 2.7 [英] Replicate Java's PBEWithMD5AndDES in Python 2.7

查看:258
本文介绍了在Python中复制Java的PBEWithMD5AndDES 2.7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我的任务是复制Java的PBEWithMD5AndDES(MD5摘要)的行为使用DES加密)在Python 2.7中。



我可以访问Python的加密工具包PyCrypto。



我试图复制的行为的Java代码:

  import java.security.spec.KeySpec; 
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;

public class EncryptInJava
{
public static void main(String [] args)
{
String encryptionPassword =q1w2e3r4t5y6;
byte [] salt = {-128,64,-32,16,-8,4,-2,1};
int iterations = 50;

try
{
KeySpec keySpec = new PBEKeySpec(encryptionPassword.toCharArray(),salt,iterations);
SecretKey key = SecretKeyFactory.getInstance(PBEWithMD5AndDES)。generateSecret(keySpec);
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt,iterations);

密码编码器= Cipher.getInstance(key.getAlgorithm());
encoder.init(Cipher.ENCRYPT_MODE,key,paramSpec);

String str_to_encrypt =MyP455w0rd;
byte [] enc = encoder.doFinal(str_to_encrypt.getBytes(UTF8));

System.out.println(encrypted =+ DatatypeConverter.printBase64Binary(enc));
}
catch(异常e)
{
e.printStackTrace();
}
}
}

对于给定的值,输出以下内容:

  encrypted = Icy6sAP7adLgRoXNYe9N8A == 

这是我的恶意尝试将以上内容移植到Python, encrypt_in_python.py


来自Crypto.Hash导入的
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $


$ b $ ='\x80\x40\xe0\x10\xf8\x04\xfe\x01'
_iterations = 50
plaintext_to_encrypt ='MyP455w0rd'

如果__main__== __name__:

Mimic Java的PBEWithMD5AndDES算法生成DES密钥
hasher = MD5.new()
hasher.update (_password)
hasher.update(_salt)
result = hasher.digest()

对于范围内的i(1,_iterations):
hasher = MD5。 new()
hasher.update(result)
result = hasher.digest()

key = result [:8]

encoder = DES.new(key)
encrypted = encoder.encrypt(plaintext_to_encrypt +''*(8 - (len(plaintext_to_encrypt )
print encrypted.encode('base64')

输出一个完全不同的字符串。



可以使用标准Python库将Java实现移植到Python实现?



显然,Python实现需要我加密的明文是八个字符的倍数,我甚至不知道如何填充我的明文输入以满足该条件。


$ b $感谢您的帮助。

解决方案

感谢GregS的评论,我能够排序这个转换! p>

为了将来参考,此Python代码模仿上述Java代码的行为:

 从Crypto.Hash导入MD5 
从Crypto.Cipher import DES

_password ='q1w2e3r4t5y6'
_salt ='\x80\x40\xe0\x10\xf8\x04\xfe\x01'
_iterations = 50
plaintext_to_encrypt ='MyP455w0rd'

#根据RFC 2898的Pad plaintext第6.1节
padding = 8 - len(plaintext_to_encrypt)%8
plaintext_to_encrypt + = chr(padding)* padding

如果__main__== __name__:

Mimic Java的PBEWithMD5AndDES算法生成DES密钥
hasher = MD5.new()
hasher.update(_password)
hasher.update(_salt)
result = hasher.digest()

对于范围内的i(1,_iterations):
hasher = MD5.new()
hasher.update(result)
result = hasher.digest()

encoder = DES.new(result [:8], DES.MODE_CBC,result [8:16])
encrypted = encoder.encrypt(plaintext_to_encrypt)

print encrypted.encode('base64')

此Python代码输出以下内容在Python 2.7中:

  Icy6sAP7adLgRoXNYe9N8A == 

再次感谢GregS指向正确的方向!


If it's not immediately obvious, let me start by saying I am not a crypto person.

I have been tasked with replicating the behavior of Java's PBEWithMD5AndDES (MD5 digest with DES encryption) in Python 2.7.

I do have access to Python's cryptography toolkit PyCrypto.

Here is the Java code whose behavior I am trying to replicate:

import java.security.spec.KeySpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;

public class EncryptInJava
{
    public static void main(String[] args)
    {
      String encryptionPassword = "q1w2e3r4t5y6";
      byte[] salt = { -128, 64, -32, 16, -8, 4, -2, 1 };
      int iterations = 50;

      try
      {
        KeySpec keySpec = new PBEKeySpec(encryptionPassword.toCharArray(), salt, iterations);
        SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterations);

        Cipher encoder = Cipher.getInstance(key.getAlgorithm());
        encoder.init(Cipher.ENCRYPT_MODE, key, paramSpec);

        String str_to_encrypt = "MyP455w0rd";
        byte[] enc = encoder.doFinal(str_to_encrypt.getBytes("UTF8"));

        System.out.println("encrypted = " + DatatypeConverter.printBase64Binary(enc));
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
    }
}

For the given values, it outputs the following:

encrypted = Icy6sAP7adLgRoXNYe9N8A==

Here's my ham-handed attempt to port the above to Python, encrypt_in_python.py:

from Crypto.Hash import MD5
from Crypto.Cipher import DES

_password = 'q1w2e3r4t5y6'
_salt = '\x80\x40\xe0\x10\xf8\x04\xfe\x01'
_iterations = 50
plaintext_to_encrypt = 'MyP455w0rd'

if "__main__" == __name__:

    """Mimic Java's PBEWithMD5AndDES algorithm to produce a DES key"""
    hasher = MD5.new()
    hasher.update(_password)
    hasher.update(_salt)
    result = hasher.digest()

    for i in range(1, _iterations):
        hasher = MD5.new()
        hasher.update(result)
        result = hasher.digest()

    key = result[:8]

    encoder = DES.new(key)
    encrypted = encoder.encrypt(plaintext_to_encrypt + ' ' * (8 - (len(plaintext_to_encrypt) % 8)))
    print encrypted.encode('base64')

It outputs a completely different string.

Is it possible to port the Java implementation to a Python implementation with standard Python libraries?

Apparently the Python implementation requires that the plaintext that I encrypt be a multiple of eight characters, and I'm not even sure exactly how to pad my plaintext input to meet that condition.

Thanks for your help.

解决方案

Thanks to GregS's comment, I was able to sort this conversion out!

For future reference, this Python code mimics the behavior of the Java code above:

from Crypto.Hash import MD5
from Crypto.Cipher import DES

_password = 'q1w2e3r4t5y6'
_salt = '\x80\x40\xe0\x10\xf8\x04\xfe\x01'
_iterations = 50
plaintext_to_encrypt = 'MyP455w0rd'

# Pad plaintext per RFC 2898 Section 6.1
padding = 8 - len(plaintext_to_encrypt) % 8
plaintext_to_encrypt += chr(padding) * padding

if "__main__" == __name__:

    """Mimic Java's PBEWithMD5AndDES algorithm to produce a DES key"""
    hasher = MD5.new()
    hasher.update(_password)
    hasher.update(_salt)
    result = hasher.digest()

    for i in range(1, _iterations):
        hasher = MD5.new()
        hasher.update(result)
        result = hasher.digest()

    encoder = DES.new(result[:8], DES.MODE_CBC, result[8:16])
    encrypted = encoder.encrypt(plaintext_to_encrypt)

    print encrypted.encode('base64')

This Python code outputs the following in Python 2.7:

Icy6sAP7adLgRoXNYe9N8A==

Thanks again to GregS for pointing me in the right direction!

这篇关于在Python中复制Java的PBEWithMD5AndDES 2.7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆