【问题标题】:XOR cipher in Java & PHP: different resultsJava 和 PHP 中的 XOR 密码:不同的结果
【发布时间】:2012-11-18 10:59:39
【问题描述】:

假设我有一个纯文本 a nice cup of milk tea,它将使用密钥 12345 进行 XOR 加密。

这个Java代码:

import sun.misc.BASE64Encoder;

import sun.misc.BASE64Decoder;

public class XORTest {

  public static void main(String args[]){

    String plaintext = "a nice cup of milk tea";
    String key = "12345";
    String encrypted = xor_encrypt(plaintext, key);
    String decrypted = xor_decrypt(encrypted, key);
    System.out.println("Encrypted: "+encrypted);
    System.out.println("Decrypted: "+decrypted);
  }

  public static String xor_encrypt(String message, String key){
    try {
      if (message==null || key==null ) return null;

      char[] keys=key.toCharArray();
      char[] mesg=message.toCharArray();
      BASE64Encoder encoder = new BASE64Encoder();

      int ml=mesg.length;
      int kl=keys.length;
      char[] newmsg=new char[ml];

      for (int i=0; i<ml; i++){
        newmsg[i]=(char)(mesg[i]^keys[i%kl]);
      }
      mesg=null; 
      keys=null;
      String temp = new String(newmsg);
      return new String(new BASE64Encoder().encodeBuffer(temp.getBytes()));
    }
    catch ( Exception e ) {
      return null;
    }  
  }
  

  public static String xor_decrypt(String message, String key){
    try {
      if (message==null || key==null ) return null;
      BASE64Decoder decoder = new BASE64Decoder();
      char[] keys=key.toCharArray();
      message = new String(decoder.decodeBuffer(message));
      char[] mesg=message.toCharArray();

      int ml=mesg.length;
      int kl=keys.length;
      char[] newmsg=new char[ml];

      for (int i=0; i<ml; i++){
        newmsg[i]=(char)(mesg[i]^keys[i%kl]);
      }
      mesg=null; keys=null;
      return new String(newmsg);
    }
    catch ( Exception e ) {
      return null;
    }  
  }}

给我:

加密:UBJdXVZUElBBRRFdVRRYWF5YFEFUUw==

解密:一杯好喝的奶茶

还有这个 PHP 代码:

<?php

$input = "a nice cup of milk tea";
$key = "12345";
$encrypted = XOR_encrypt($input, $key);
$decrypted = XOR_decrypt($encrypted, $key);

echo "Encrypted: " . $encrypted . "<br>";
echo "Decrypted: " . $decrypted . "<br>";

function XOR_encrypt($message, $key){
  $ml = strlen($message);
  $kl = strlen($key);
  $newmsg = "";
  
  for ($i = 0; $i < $ml; $i++){
    $newmsg = $newmsg . ($msg[$i] ^ $key[$i % $kl]);
  }
  
  return base64_encode($newmsg);
}

function XOR_decrypt($encrypted_message, $key){
  $msg = base64_decode($encrypted_message);
  $ml = strlen($msg);
  $kl = strlen($key);
  $newmsg = "";
  
  for ($i = 0; $i < $ml; $i++){
    $newmsg = $newmsg . ($msg[$i] ^ $key[$i % $kl]);
  }
  
  return $newmsg;
}

?>

给我:

加密:MTIzNDUxMjM0NTEyMzQ1MTIzNDUxMg==

解密:

想知道为什么两个结果不同。 我必须先承认 PHP 不是我喜欢的。

顺便说一句,我将它用于玩具项目,因此不需要高安全性。

【问题讨论】:

  • 我不是安全专家,但这是我的看法:由于您在 Java 和 PHP 中都使用 base64_encode,因此 base64 编码是不同的。看看这个用 java 和 php 进行编码的解决方案:stackoverflow.com/questions/11002603/…
  • 我的回答有望解决您的一个问题。在您的 PHP 示例输出中,您似乎建议您的解密输出为空白。这是正确的还是复制/过去的错误?
  • @DuncanJones 这很正确,是的,它确实解决了问题。

标签: java php cryptography encryption


【解决方案1】:

在您的 PHP 加密方法中,您有以下代码:

for ($i = 0; $i < $ml; $i++){
  $newmsg = $newmsg . ($msg[$i] ^ $key[$i % $kl]);
}

但是,$msg 没有在任何地方定义。那应该是$message

【讨论】:

  • 从枪、枪套中吹出烟雾…… ;-)
  • 是的,邓肯,你是对的。有时,当您困倦时,很难发现这种错误。故事的寓意:总是使用 error_reporting(E_ALL) :)
猜你喜欢
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-30
相关资源
最近更新 更多