【问题标题】:Java to PHP code differenceJava 到 PHP 代码的区别
【发布时间】:2016-03-26 01:23:11
【问题描述】:

我收到了一段描述令牌生成“算法”的代码。此代码是用 Java 编写的,可以正常工作。 给定的 Java 代码必须保持原样,但是,我的要求是在 PHP 应用程序中使用相同的“算法”,我很难检索到相同的结果。

Java 代码:

public static void main(String[] args)
        throws
        UnsupportedEncodingException,
        NoSuchAlgorithmException {

    // Let's stick to a fixed date for this SO question
    //DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
    //dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    //String date = dateFormat.format(new Date());
    String date = "201603251605";
    String name = "some_dummy_data_one";
    String size = "some_dummy_data_two";

    // MD5 'name'
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(name.getBytes());
    byte[] md5name = md5.digest();

    // What happens here is beyond me - How would one translate this to PHP?
    byte[] sizeBytes = (size + date).getBytes();
    byte[] tokenBytes = new byte[md5name.length + sizeBytes.length];

    System.arraycopy(sizeBytes, 0, tokenBytes, 0, sizeBytes.length);
    System.arraycopy(md5name, 0, tokenBytes, sizeBytes.length, md5name.length);

    // SHA256
    MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
    sha256.update(tokenBytes);
    byte[] tokenHash = sha256.digest();

    System.out.println(Base64.getEncoder().encodeToString(tokenHash));
}

打印出来:

LsPw/5/4uKmQfVaU1LRASxG89mgMt7OxX+h7JGRo1ZU=

最终和理想情况下,我希望有一种快速的方法来使用 PHP 代码获得相同的结果,但我有一种冲动去了解正在发生的事情,而不是仅仅达到预期的结果。

现在尝试表明我至少做了一些功课,我不只是在寻找某人为我做我的工作,直到字符串的 MD5 转换,我已经设法得到单个字符串的相同 base64 编码 SHA256 字符串,跳过包含“System.arrayCopy”位的中间代码块

Java 代码:

public static void main(String[] args)
        throws
        UnsupportedEncodingException,
        NoSuchAlgorithmException {

    String date = "201603251605";

    // MD5 'name'
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(date.getBytes());
    byte[] md5Date = md5.digest();

    // SHA256
    MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
    sha256.update(md5Date);
    byte[] tokenHash = sha256.digest();

    System.out.println(Base64.getEncoder().encodeToString(tokenHash));
}

PHP 代码:

private function generateToken() {
    $md5Date = md5("201603251605", true);        
    $shaString = hash("sha256", $md5Date, true);

    return base64_encode($shaString); 
}

Java 输出:

mEkkRlBkwyoWFMsA+v/hP/m9sD6FdzM6LZHIORtr260=

PHP 输出:

mEkkRlBkwyoWFMsA+v/hP/m9sD6FdzM6LZHIORtr260=

所以根据上述,我的单个字符串的 md5 和 sha 工作正常,但这不是问题。 问题在于理解当多个字符串被定义并在 Java 代码中混合在一起时会发生什么。为什么它看起来过于复杂,在 PHP 中是否有简单的方法?

有人可以解释一下 MD5 和 SHA256 生成之间发生了什么,以便我可以将其转换为 PHP 代码吗?我试图阅读 Java System.arrayCopy 文档,但我觉得我没有足够的经验/聪明来理解那里发生的事情。如果有一个简单的解决方案,我将非常感激。

【问题讨论】:

  • 真的不明白这个问题。即使你有很多话。你似乎在问一个问题,然后解决它。那么真正的问题是什么?
  • @KyleK 他只是想知道 Java 代码的中间部分在做什么。看看他的内联 cmets。
  • @KyleK,有很多话是有原因的。阅读有帮助;)

标签: java php md5 sha


【解决方案1】:

当你意识到它实际上做的事情是多么简单时,你会踢自己。

<?php
$date = "201603251605";
$name = "some_dummy_data_one";
$size = "some_dummy_data_two";

$md5_name = md5($name, true);

$token_bytes = $size.$date.$md5_name;

$token_hash = hash("sha256", $token_bytes, true);

echo base64_encode($token_hash);

arraycopy 只是附加sizedatemd5name 的一种相当混乱的方式。为什么Java代码如此复杂我不知道。

【讨论】:

  • 我正在 OP 回复我的实际帐户 - 不完全确定我为什么登录到一个新帐户。你是对的——我理所当然地给了自己一个大掌。谢谢!
【解决方案2】:

听起来您已经找到了如何在 PHP 中执行此操作的答案。 Java 代码的作用基本相同。这就是它正在做的事情......

// This concatenates size+date and the md5 hash, and then creates a SHA-256 hash from that value.

byte[] sizeBytes = (size + date).getBytes();  //Get byte array of size and date concatenation
byte[] tokenBytes = new byte[md5name.length + sizeBytes.length]; //Create the right size byte array to fit md5 and size+date

System.arraycopy(sizeBytes, 0, tokenBytes, 0, sizeBytes.length); // copies the size+date byte array into the first part of the token bytes byte array.
System.arraycopy(md5name, 0, tokenBytes, sizeBytes.length, md5name.length); //concatenates the md5 hash and size+bytes into the tokenBytes array 

// SHA256
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");//Get the SHA-256 algorithm instance
sha256.update(tokenBytes); // give it a value to hash
byte[] tokenHash = sha256.digest(); // create SHA-256 hash from token bytes

【讨论】:

  • 感谢达斯汀提供的额外信息。您是否看到了为什么采用这条路线而不是将字符串和 MD5 连接为字符串的原因?似乎开发人员已经竭尽全力让它变得不必要的复杂,IMO。
  • 如果我不得不猜测我会说在某个时候他们使用更安全的“随机”值而不是大小和日期字符串来播种哈希,然后可能需要一个静态字符串值来进行测试?如果他们之前使用过更安全的东西,那么他们会想要使用字节值。使用此代码了解令牌值所需的只是大小、名称和日期。
猜你喜欢
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 2011-11-03
  • 1970-01-01
相关资源
最近更新 更多