使用RSA加密的php文本和base64编码在android中解密后仍然保留一些

时间:2013-11-16 18:31:21

标签: java android encryption rsa phpseclib

我正在使用android创建密钥对,我使用http post将公钥发送到使用php脚本的wamp服务器mysql数据库。

成功接收密钥后,php脚本使用密钥对字符串进行加密,并使用base43对其进行编码,sripts回显一个json对象到android .....我使用base64进行解码,然后使用私钥解密文本然后再对base64进行编码以查看它。

PHP

$rawKey = $_POST['rawKey'];
$publicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . chunk_split($rawKey) .  
"-----END RSA PUBLIC KEY-----";
$rsa = new Crypt_RSA();
$rsa->loadKey($publicKey); // public key
$AESKeyString = "some text";
$AESKeyString = $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$ciphertext = $rsa->encrypt($AESKeyString);
$ciphertext = base64_encode($ciphertext);
$response = array('' => $ciphertext);
echo json_encode($response);

的java

public String Decrypt(String encryptedKey) {
    Cipher cipher = null;
    try {
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} try {
    cipher.init(Cipher.DECRYPT_MODE, privKey);
} catch (InvalidKeyException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
byte[] cipherData = null;
try {
    cipherData = cipher.doFinal(Base64.decode(encryptedKey, Base64.NO_WRAP));
} catch (IllegalBlockSizeException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (BadPaddingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
    String cipherString = Base64.encodeToString(cipherData, Base64.NO_WRAP);
    Log.d("SecCom", cipherString);
    return cipherString;
}

问题是,虽然解密中没有错误,但文本总是垃圾....但是这个垃圾是唯一的,并且对于给出明文而言......也就是说java中的“hello world”总是转换为“n; lk @; la”,只更改纯文本会改变解密的垃圾。

我看了很多关于stackoverflow的例子,这似乎对他们有效,纯粹出于一些直觉,我在加密它之前在php字符串中添加了base64解码

$AESKeyString = base64_decode("some text");

和中提琴解决了这个问题,除了现在我在java中获得原始字符串除了删除所有空格.....并且最后一个字符被g ==

替换

即“some text”显示为“sometexg ==”

我尝试了很多文本,但是通过所有没有空格并且最后一个字符被g ==

替换,这是不变的

在我最后的PHP脚本中,我将为aes生成随机字节,对它们进行加密,然后对它们进行编码以发送到java。请在您提供给我的解决方案中牢记这一点.....

为什么在php中添加base64.decode对我来说是必要的呢?对于其他人来说,它只是开箱即用

感谢

1 个答案:

答案 0 :(得分:0)

正如我在评论中提到的......我的问题是不了解字符串和编码部分以及它如何转换为java .....

好吧,我给了它一个去,做了一些阅读并重写了php方面,它在第一次尝试工作.....

....这里是一个完整的PHP代码.... java代码不需要改变....我也评论过它

PHP     //获取发布的公钥         $ pumpumString = $ _POST ['pumpum'];

    //format public key in CRYPT format
    $publicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . chunk_split($pumpumString) . 
    "-----END RSA PUBLIC KEY-----";

    //initialise Algorithm
    $rsa = new Crypt_RSA();
    $rsa->loadKey($publicKey); // public key
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

    //generate new AES Session Key
    $AESKey = rand_sha1(32); //a custom created function

    $AESKeyDecoded = base64_decode($AESKey);

    //encrypt AES Session Key
    $ciphertext = $rsa->encrypt($AESKeyDecoded);

    //base 64 encode it for transfer over internet
    $ciphertextEncoded = base64_encode($ciphertext);

    //prepare array for sending to client
    $response = array('plum' => $ciphertextEncoded);

    //write the encoded and decoded AES Session Key to file for comparison
    $file = fopen('key.txt', 'w');
    fwrite($file, "\n". $AESKey);

    //echo JSON
    echo json_encode($response);

之前让我困惑的一件事就是为什么我需要在加密之前对我的明文进行base64解码....我能够弄清楚的是,php可能使用ASCII来存储字符串。因为在java中我使用base64_encode从解密的字节数组中获取解密的字符串.....我需要首先解码我的ascii明文字符串以在java中重新生成......(我可能已经措辞了有点不连贯......请随意改写它。)

如果你觉得我得出了错误的结论或者某些事情可以改进,请告诉我,我将此标记为已解决....

我也曾要求一种生成随机aes密钥的方法.....下面是我以前使用的函数.....礼貌https://stackoverflow.com/a/637322/2208279

PHP

function rand_sha1($length) {
    $max = ceil($length / 40);
    $random = '';
    for ($i = 0; $i < $max; $i ++) {
        $random .= sha1(microtime(true).mt_rand(10000,90000));
    }
return substr($random, 0, $length);
}

我正在使用aes256所以我使用32作为此函数的参数....将其修改为16为128

谢谢....希望这有助于某人。