Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.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
Java 在不同的平台上使用相同的哈希+加密生成非身份值_Java_Android_Encryption_Hash - Fatal编程技术网

Java 在不同的平台上使用相同的哈希+加密生成非身份值

Java 在不同的平台上使用相同的哈希+加密生成非身份值,java,android,encryption,hash,Java,Android,Encryption,Hash,我正在为一个社交网站编写一些web服务。android将利用这些web服务制作android应用程序。由于设计网站的人不再接触,我查看了使用spring框架用java编写的整个网站代码。我正在用php编写web服务 现在,当我试图向一个php页面发送post请求,确认给定的用户名和密码组合是否正确,然后返回一个会话id。但是我无法获得正确的哈希方法来获得保存在数据库中的正确哈希值。 因此,每次我都会被php代码拒绝 我在网站代码中找到的加密如下: public static final sync

我正在为一个社交网站编写一些web服务。android将利用这些web服务制作android应用程序。由于设计网站的人不再接触,我查看了使用spring框架用java编写的整个网站代码。我正在用php编写web服务

现在,当我试图向一个php页面发送post请求,确认给定的用户名和密码组合是否正确,然后返回一个会话id。但是我无法获得正确的哈希方法来获得保存在数据库中的正确哈希值。 因此,每次我都会被php代码拒绝

我在网站代码中找到的加密如下:

public static final synchronized String encrypt(String plaintext, String algorithm, String encoding) throws Exception
{
  MessageDigest msgDigest = null;
  String hashValue = null;
  try
  {
    msgDigest = MessageDigest.getInstance(algorithm);
    msgDigest.update(plaintext.getBytes(encoding));
    byte rawByte[] = msgDigest.digest();
    hashValue = (new BASE64Encoder()).encode(rawByte);

  }
  catch (NoSuchAlgorithmException e)
  {
    System.out.println("No Such Algorithm Exists");
  }
  catch (UnsupportedEncodingException e)
  {
    System.out.println("The Encoding Is Not Supported");
  }
  return hashValue;
}
例如,如果我给出的密码是monkey123作为password,那么它给出的哈希值在base 64中编码为:hge2WiM7vlaTTS1qU404+Q==

现在,在php中挣扎了几个小时之后,我意识到我可以在android中完成上述过程。因此,我编写了以下代码:

MessageDigest pwdDigest=MessageDigest.getInstance("MD5");
pwdDigest.update(password.getBytes("UTF-16"));
byte rawbyte[]=pwdDigest.digest();
String passwordHash=Base64.encodeToString(rawbyte,Base64.DEFAULT);


URL url = new URL(loginURL);

HttpURLConnection Connection = (HttpURLConnection) url.openConnection();

Connection.setReadTimeout(10000);
Connection.setAllowUserInteraction(false);

Connection.setDoOutput(true);

//set the request to POST and send

Connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

DataOutputStream out = new DataOutputStream(Connection.getOutputStream());
out.writeBytes("username=" + URLEncoder.encode(username, "UTF-8"));
out.writeBytes("&password="+URLEncoder.encode(passwordHash,"UTF-8"));
out.flush();
out.close();
if(Connection.getResponseCode()==200){
  String data="Connected";            
  return data;
} else 
  return Connection.getResponseCode()+": "+Connection.getResponseMessage();
我希望这会成功,因为在这两种情况下,我都在执行相同的过程来加密密码,但令人惊讶的是,这并没有给出如下哈希值: hge2WiM7vlaTTS1qU404+Q==但它给出了:nZlvVe7GSS2Zso1dOwJrIA==


我真的很难找到这两个不一样的原因。任何帮助都将不胜感激。

我不希望MD5在不同平台上有所不同。它是稳定的,有很好的文档记录,是核心库的一部分。如果这在安卓版本中被破坏,那么在那部手机上就什么也用不上了

重新编码到UTF-8是无害的,因为所有Base64字符都适合较低的ASCII范围。base64字母表的三个字符需要URL编码,但如果出现错误,您可能会看到转义

Base64不太稳定,有很多不同的实现,没有单一的规范实现,但也不完全是火箭科学。再说一次,我并不期望一个错误的实现能够真正实现,但是Base64步骤可能是产生差异的地方

就我个人而言,我怀疑这个错误是在password.getBytesUTF-16调用期间引入的。验证这种预感的一种快速方法是在两种平台上的调试器中检查生成的字节数组。根据,UTF-16编码将使用big-endian字节顺序,而您的PHP代码可能默认为little-endian,因为它在x86上运行,并且没有字节顺序标记。我对PHP的了解还不足以判断这种行为是否定义良好。尝试修改Java代码以使用password.getBytesUTF-16LE,看看这是否有区别


旁注:对于散列密码,MD5不再被认为是安全的;您可能希望使用像scrypt或PBKDF2这样的东西进行大量轮次和随机salt,但这本身就是一个主题。

您在网站代码中使用的编码是什么?加密函数称为:公共字符串getEncryptPassword{try{return MyPasswordEncrypt.encryptgetPassword,MD5,UTF-16;}捕获异常e{e.printStackTrace;return encryptPassword;}}在使用UTF-16后,您将其作为UTF-8编码发送。这可能是个问题。我也尝试将android发布代码更改为UTF-16,这也没有帮助。您是否也像在android应用程序中一样对网站代码进行编码。Barend,我完全同意你的看法。事实上,我已经检查了output password.getBytesUTF-16在这两种情况下会给出什么,但它并不相同。因此,我可以确认问题出在base64或md5之外。它是UTF-16。在android中,password.getBytesUTF-16给出的数组值为:-1-249049052020490490500490980990,而在java中,它给出的数组值为:-2-1049049049052049050049097098099,所以,这似乎是问题所在。。有什么看法吗?巴伦德,我已经解决了这个问题。。正如您所看到的,数组的值只是邻接地错位了,我只是交换了这些值,这样它就生成了一个正确的散列..它就是这样。谢谢你的帮助