问题描述
我正在尝试在PHP中实现Java的StandardStringDigester摘要函数,以使用SHA-1算法来摘要字符串。我没有加密方面的经验,因此我尝试了一些事情,但并不了解它们。 Java的工作示例如下:
import java.net.URLEncoder;
import org.jasypt.digest.StandardStringDigester;
import java.io.UnsupportedEncodingException;
public class Main
{
public static void main (String[]args)
{
String x = "XUXoV2VYc7zYJ8UN";
int n = 854;
StandardStringDigester clientsd = new StandardStringDigester ();
clientsd.setIterations (n - 1);
clientsd.setAlgorithm ("SHA-1");
clientsd.setSaltSizeBytes (0); //no salt
String clientDigest = clientsd.digest (x);
String URLclientDigest = "a";
try {
URLclientDigest = URLEncoder.encode (clientDigest,"UTF-8");
} catch(UnsupportedEncodingException ex){
System.out.println("Encoding not supported");
ex.printstacktrace();
}
System.out.println (URLclientDigest);
}
}
在PHP中,我尝试了几件事:
$n = 854;
$x = 'XUXoV2VYc7zYJ8UN';
return hash_pbkdf2('sha1',$x,null,$n);
我也用$n -1
尝试了上面的代码。
在以上示例中,x
是消息,n
是迭代。
我不确定我在这里做什么。也许有人可以指向我指向一个PHP库,否则任何指导都将不胜感激。
解决方法
根据StandardStringDigester
(属于Jasypt库的一部分)的文档,哈希的生成方式如下:
创建摘要所采取的步骤是:
- 字符串消息将转换为字节数组
- 生成指定大小的盐(请参见SaltGenerator)。
- 盐字节将添加到消息中。
- 将哈希函数完全应用于salt和message,然后应用于函数本身的结果, 指定(迭代)。
- 如果由盐生成器指定(请参见SaltGenerator.includePlainSaltInEncryptionResults()),则未消化 盐和哈希函数的最终结果是串联在一起的, 结果返回了。
- 连接的结果以BASE64或HEXADECIMAL进行编码,并以ASCII字符串形式返回。
由于在您的情况下不使用盐,因此可能的PHP实现为:
$n = 854;
$x = 'XUXoV2VYc7zYJ8UN';
$hash = $x;
for ($counter = 0; $counter < $n - 1; $counter++){
$hash = hash('sha1',$hash,true);
}
print(base64_encode($hash)); // QGFgek+pfZ6nMk8Jn3stOe5KeEY=
其结果QGFgek+pfZ6nMk8Jn3stOe5KeEY=
与Java代码类似(在URL编码之前)。
注意:如果Java代码中使用了盐(例如,使用ByteArrayFixedSaltGenerator
),则必须将PHP代码中的盐与循环之前的消息连接起来:$hash = $salt . $x;
(而不是{{ 1}})。