【问题标题】:PHP encrypts a password with RSA decryption and Android sees some junk data plus the true data after decryptionPHP 使用 RSA 解密加密密码,Android 看到一些垃圾数据以及解密后的真实数据
【发布时间】:2018-11-13 14:35:45
【问题描述】:

我正在使用 RSA 和 AES 加密/解密
我在 Android 中创建 RSA 公钥和私钥
我将公钥发送到 PHP 服务器

利用AES加密,PHP用密码对一些大数据进行加密,并利用RSA加密和接收到的公钥,对密码进行编码,然后用密码和编码后的加密密码返回加密的大数据,其中encode函数是如下: base64_encode(the encrypted password)

在Android中,我首先对编码后的加密密码进行解码,解码指令如下:Base64.decode(the encoded encrypted password, Base64.DEFAULT)

PHP代码如下:

openssl_public_encrypt($password, $encrypted, $public_key);
$mystr= base64_encode($encrypted);
echo "mystrStart=$mystr mystrEnd\n"; //mystr will be retrieved in Android

Android 代码如下:

cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] encryptedBytes,decryptedBytes;
encryptedBytes = Base64.decode(mystr, Base64.DEFAULT);
decryptedBytes = cipher.doFinal(encryptedBytes);
String DecryptedPassword = new String(decryptedBytes);

问题是我在 DecryptedPassword 末尾看到了密码,但在看到密码之前还有一些其他垃圾数据:

PHP 中的密码是“Hellooooo”

Android中接收到的mystr(加密后的密码)如下:

sNfmwifoIEqXQzzge0zOFmBTFPlDqQZkAWqOPtGe3jNuI/zdV4SsCTxzcNZvww5RaaMOZ4ubQWrGXLuyuimKeQ==

最终结果(DecryptedPassword)如下:

����/ +�*@7JY��,��7��$C�-|8�[��p��Ĭ����,9v��}��Hellooooo

编辑:
代码如下:

        KeyPairGenerator kpg;
        KeyPair kp;
        PublicKey publicKey;
        final PrivateKey privateKey;

        try {
            kpg = KeyPairGenerator.getInstance("RSA");
            kpg.initialize(512);
            kp = kpg.genKeyPair();
            publicKey = kp.getPublic();
            privateKey = kp.getPrivate();

            byte[] pKbytes = Base64.encode(publicKey.getEncoded(), 0);
            String pK = new String(pKbytes);
            String pubKey = "-----BEGIN PUBLIC KEY-----\n" + pK + "-----END PUBLIC KEY-----\n";

            Log.e(TAG, "pubKey:"+pubKey); 

然后这个pubKey被保存到一个名为U.txt的文件中,然后发送到服务器

SendJSONToServerTest someTask = new SendJSONToServerTest(getApplicationContext(), "FileName"+".txt", PHP_address, getApplicationContext().getFilesDir().getPath() + "/" + "U.txt", new SendJSONToServerTest.OnEventListener<String>() {
                @Override
                public void onSuccess(String result) {

                    Log.e(TAG, "log1 = "+result);
                    String mstr = getBetweenStrings(result,"mystrStart=","mystrEnd");
                    Log.e(TAG, "log2 = "+mstr);

                    try {
                        cipher.init(Cipher.DECRYPT_MODE, privateKey);
                        byte[] encryptedBytes, decryptedBytes;
                        encryptedBytes = Base64.decode(mstr, Base64.DEFAULT);
                        decryptedBytes = cipher.doFinal(encryptedBytes);

                        String DecryptedPassword = new String(decryptedBytes);
                        Log.e(TAG, "log3= "+DecryptedPassword);

                     } catch(GeneralSecurityException e) {
                         System.out.println(e);
                     }
                     Log.e(TAG, "Endddddddddddddd");
                }

                @Override
                public void onFailure(String f) {
                    Log.e(TAG, "errR.......");
                }
            });
            someTask.execute();

文件内容相关的PHP代码:

$fileContentStr = file_get_contents($_FILES["uploaded_file"]["tmp_name"]);
echo "\nfileContentStr = {$fileContentStr}\n";

$public_key = $fileContentStr;
echo "\npublic_key = {$public_key}\n";

【问题讨论】:

  • mystr (the encoded encrypted password) received in Android is as following:.。好的。但是它和php发送的一样吗?你一开始就检查了吗?
  • 是的,是一样的
  • 我也用 phpseclib 进行了测试,当 setEncryptionMode 设置为 CRYPT_RSA_ENCRYPTION_OAEP 时,Hellooooo 在日志中看不到,但当我将其更改为 CRYPT_RSA_ENCRYPTION_PKCS1 结果如下:7���>-B�ğ��$�d����~��*0�b4 �i��Ҏ��̞cB���� 类似于openssl的hellooo
  • 请尝试在 php 端进行解码和解密以进行测试。你得到了什么?也尝试在 Android 端做所有事情。然后一步步比较。我在您的故事中想念的是所有步骤中使用的数组和字符串的大小/长度。确定它们并进行比较。
  • 您还可以发布完整的代码,我们只需要复制/粘贴即可对其进行测试。

标签: php android


【解决方案1】:

我也有同样的问题,去搜索,找到了答案here

基本上,消息被填充,原始方法之前的字节是 0x00 字节(NUL 字符)。

以下代码是从删除填充并返回原始消息的链接中提取的。

def pkcs1_unpad(text):
    if len(text) > 0 and text[0] == '\x02':
        # Find end of padding marked by nul
        pos = text.find('\x00')
        if pos > 0:
            return text[pos+1:]
    return None

我正在用 python 解码加密的消息,但很容易将它移植到 PHP。

我希望这对你也有帮助。

【讨论】:

  • 你的意思是“Hellooooo”被填充 => 让我们将其命名为“A”,然后加密 => 让我们将其命名为“B”,然后编码 => 让我们将其命名为“C”,然后在 Android 中解码=> 命名为“D”,然后用私钥解密 => 命名为“E”,现在哪个(AE)是pkcs1_unpad函数(文本)的参数?
  • “E”,解密的消息,是 pkcs1_unpad(text) 的参数。 E 是文本。这意味着如果我们认为垃圾填充是“J”,那么 E = J + A。
  • 将上述内容应用到您的消息中,我们会发现“Hellooooo”中“H”之前的字符串中的字节实际上是nul字符(\0或0x00)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2013-04-22
  • 2019-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
相关资源
最近更新 更多