Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.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
当使用SecretKeyFactory生成secret时,Java byterray to string必须等于python bytearray string_Java_Python_Character Encoding_Cryptography_Pbkdf2 - Fatal编程技术网

当使用SecretKeyFactory生成secret时,Java byterray to string必须等于python bytearray string

当使用SecretKeyFactory生成secret时,Java byterray to string必须等于python bytearray string,java,python,character-encoding,cryptography,pbkdf2,Java,Python,Character Encoding,Cryptography,Pbkdf2,我的任务是将一些python加密代码重写为java。我是python新手。Python代码: from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.backends import default_backend backend = default_backend() PASSWORD = bytes((1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

我的任务是将一些python加密代码重写为java。我是python新手。Python代码:

from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
backend = default_backend()  



PASSWORD = bytes((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16))

key = PBKDF2HMAC(hashes.SHA256(), 32, salt, iterations, backend).derive(PASSWORD)
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes

salt = b'salt'
iterations = 512
PASSWORD = bytes((255, 250, 170, 187, 188, 204, 221, 221, 255, 170, 170, 170, 170, 170, 170, 187))
key = PBKDF2HMAC(hashes.SHA256(), 32, salt, iterations).derive(PASSWORD)

print(key.hex()) # d8aa4772e9648572611fe6dca7f653353de934cdb3b29fab94eb13ba2b198b9f
我的java实现:

import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.PBEKeySpec;
     byte[] PASSWORD = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
    SecretKey tmp = factory.generateSecret(new PBEKeySpec(new String(PASSWORD).toCharArray(), salt, iterations, 256));
    byte[] key = tmp.getEncoded();
正如您所看到的,密码是一个字节数组,我从一个十六进制字符串中获得,即010203…0F10,我不能更改它(即,不能在python实现中将其指定为字符串,因为我知道服务器也会将密码转换为字节数组)。所有这些都可以使用这个虚拟密码,即python和java代码生成的密钥是相等的。但当密码更改为任意时,我面临一个问题,例如afffffffdbgehth。。。。 正如我所理解的,java字节数组表示为有符号整数的问题。例如,当我将十六进制“fffaaabbccddffaaaaaaaaabb”转换为字节数组时,它将是字节数组[-1,-6,-86,-69,-68,-52,-35,-1,-86,-86,-86,-86,-86,-86,-69],但在python中它将是[255,250,170,187,188,204,221,221,255,170,170,170,170,187]。然后,当我将java字节数组转换为PBEKeySpec构造函数的charArray-new-PBEKeySpec(新字符串(新字节[]{-1,-6,-86,-69,-68,-52,-35,-35,-1,-86,-86,-86,-86,-69})时,ToCharray()会意外地工作

如何更改java代码以接收与python中相同的密钥?据我所知,我必须将java字节数组字符串编码为与python.derive(…)方法中相同的值。 提前谢谢

更新:

salt       = b'salt'
PASSWORD = = bytes((255, 250, 170, 187, 188, 204, 221, 221, 255, 170, 170, 170, 170, 170, 170, 187))
key = PBKDF2HMAC(hashes.SHA256(), 32, salt, 512, backend).derive(PASSWORD)

应该给出相同的结果。它适用于新字节[]{1,2,3,4,….16}密码

UPDATE2:我已将密码更改为unsigned int[],但无论如何它都不起作用:

    char[] password = new char[PASSWORD.length];
            for (int i = 0; i<PASSWORD.length; password[i] = (char)(PASSWORD[i++] & 0xFF));
    var key = secretKeyFactory
                    .generateSecret(new PBEKeySpec(password, "salt".getBytes(), 512, 256))
                    .getEncoded();
    
char[]password=新字符[password.length];

对于(int i=0;i您在Java代码中使用的是
SHA1
,而在Python代码中使用的是
SHA256
,这就是为什么您会得到不同的结果。除了不同的摘要之外,使用
PBKDF2WithHmacSHA256
(第1节),问题是使用
PBKDF2WithHmacSHA256
派生的密钥是
PBKDF2KeyImpl
的一个实例,它需要一个字符串作为密码。该字符串在
PBKDF2KeyImpl
中用UTF8编码(请参见类的文档)。但是,这里的密码是一个(任意的)字节序列,通常与UTF8不兼容,因此在UTF8解码过程中数据会损坏。一种可能的解决方案是用BouncyCastle的
PKCS5S2ParametersGenerator
替换
PBEKeySpec
,后者希望密码作为字节数组(在
init
中):

现在,结果与Python代码的结果相匹配:

from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
backend = default_backend()  



PASSWORD = bytes((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16))

key = PBKDF2HMAC(hashes.SHA256(), 32, salt, iterations, backend).derive(PASSWORD)
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes

salt = b'salt'
iterations = 512
PASSWORD = bytes((255, 250, 170, 187, 188, 204, 221, 221, 255, 170, 170, 170, 170, 170, 170, 187))
key = PBKDF2HMAC(hashes.SHA256(), 32, salt, iterations).derive(PASSWORD)

print(key.hex()) # d8aa4772e9648572611fe6dca7f653353de934cdb3b29fab94eb13ba2b198b9f

-1
255
是相同的字节值
0111111b
。第一个是有符号解释(2的补码),第二个是无符号解释。这取决于你(通常是人类)的方式希望解释它。计算机不会混淆。是的,我理解。但正如我从实验中看到的,java和python实现是不同的。当我开始使用大于127的字节时,我会得到意外的结果。然后显示代码,从中你会得到意外的结果。不要将字节数组打印为值。而是使用标准化方法,如e hex编码或base64编码,然后您甚至可以在不同的编程语言/运行时之间进行比较。谢谢。很抱歉我添加了旧代码。现在我使用PBKDF2和HMACSHA256,但仍然不起作用。我修复了。非常感谢@ValeriyK。-不客气。是的,SHA256更加一致,我已经相应地更新了它。