所以我有我的代码中的具体问题。它有时有效,有时不会,我不知道为什么。AES和CBC在Android和PHP通过Base64
它应该是如何工作的:的Android加密使用AES/CBC/PKCS5Padding随机IV和我的秘密密钥的消息,转换加密消息,Base64和使用POST方法将其发送到服务器。 服务器将消息转换为二进制形式,将其解密并将笑脸附加到消息。接下来将消息发送回Android。如果消息为空,则服务器向我发送“空白”文本。
工作原理:我总是收到来自服务器的数据,因此连接正常。不幸的是,我得到3类型答案:
- 我笑着消息 - 这是确定
- “空......”的文字 - 但不知何故解密的作品,PHP调试模式没有问题
- 一个错误,我的IV过短 - 很少
一条线索:我看着用base64数据,发现情况2当用base64字符串为“+”字符出现,但我不知道它是如何能帮助。
Android部分发送数据做服务器:
HttpURLConnection urlConnection;
String message = null;
String answer = null;
String data = "a piece of data";
try {
byte[] wynikByte = encrypt(data.getBytes("UTF-8"));
message = Base64.encodeToString(wynikByte, Base64.DEFAULT);
} catch (UnsupportedEncodingException ex){
Log.e("CRYPT", "Not working");
}
try {
// Connect to server
urlConnection = (HttpURLConnection) ((new URL(url).openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestMethod("POST");
urlConnection.connect();
// Send to server
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write("dane=" + message);
writer.close();
outputStream.close();
// Read answer
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
answer = sb.toString();
} catch (UnsupportedEncodingException | IOException ex) {
e.printStackTrace();
}
return message + "\n" + answer;
Android的加密方法:
public static byte[] encrypt(byte[] plaintext) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = new SecretKeySpec(hexStringToByteArray(klucz2), "AES");
SecureRandom random = new SecureRandom();
byte iv[] = new byte[16];//generate random 16 byte IV AES is always 16bytes
random.nextBytes(iv);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
byte[] ciphertext = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, ciphertext, 0, iv.length);
System.arraycopy(encrypted, 0, ciphertext, iv.length, encrypted.length);
return ciphertext;
} catch (InvalidKeyException | NoSuchAlgorithmException
| NoSuchPaddingException
| IllegalBlockSizeException | InvalidAlgorithmParameterException
| BadPaddingException e) {
throw new IllegalStateException(
"CBC encryption with standard algorithm should never fail",
e);
}
}
与我的秘密密钥的PHP文件中的Android应用程序也使用:
<?php
if (isset($_POST['dane']))
{
$dane = $_POST['dane'];
$key = pack('H*', "73f826a001837efe6278b82789267aca");
$blocksize = mcrypt_get_block_size('rijndael_128', 'cbc');
$ciphertext = base64_decode($dane, $powodzenie);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv_old = substr($ciphertext, 0, $iv_size);
$ciphertext = substr($ciphertext, $iv_size);
$plaintext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC, $iv_old);
$plaintext = pkcs5_unpad($plaintext);
if($plaintext == "")
{
echo "Empty...";
return;
}
$plaintext = $plaintext . " :)";
echo $plaintext;
} else {
echo "Dane is empty";
}
// PHP don't have pkcs5 methods to pad
function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
// PHP don't have pkcs5 methods to unpad
function pkcs5_unpad($text)
{
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -1 * $pad);
}
?>
好的解决方案1运行良好!只有一个例外 - '+'是'%2B' :) –