当前位置: 首页 > 知识库问答 >
问题:

如何将密钥从Java发送到PHP?(使用Android Studio

空谦
2023-03-14

如何将< code>SecretKeySpec或< code>SecretKey的数据从< code>Java发送到< code>PHP?当我将它转换为< code>String(用RSA加密并发布到PHP)时,我得到一些带问号的菱形。

我尝试使用utf8_decode但是这个问题仍然存在。

编辑:

我用PHP生成了RSA Keypair,并将公钥发送给Java。在Java中,我想生成一个AES_Key并使用AES加密一个明文,然后将一个加密的明文和AES_Key(用RSA_Public_Key加密)从Java发送到PHP。以下代码代表了该项目的AES加密/解密步骤:

Java:

public static class ApiCrypter {

    private String iv = "0000000000000000";
    private byte[] secretkey;     //="mysecretkeyyyyyy";
    private IvParameterSpec ivspec;
    private SecretKeySpec keyspec;
    private Cipher cipher;

    public ApiCrypter(byte[] key)
    {
        secretkey=key;
        ivspec = new IvParameterSpec(iv.getBytes());
        keyspec = new SecretKeySpec(secretkey, "AES");

        try {
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }

    public byte[] encrypt(String text) throws Exception
    {
        if(text == null || text.length() == 0) {
            throw new Exception("Empty string");
        }
        byte[] encrypted = null;
        try {
            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            encrypted = cipher.doFinal(text.getBytes("UTF-8"));
        }
        catch (Exception e) {
            throw new Exception("[encrypt] " + e.getMessage());
        }
        return encrypted;
    }

    public byte[] decrypt(String code) throws Exception
    {
        if(code == null || code.length() == 0) {
            throw new Exception("Empty string");
        }
        byte[] decrypted = null;
        try {
            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
            decrypted = cipher.doFinal(hexToBytes(code));
        }
        catch (Exception e) {
            throw new Exception("[decrypt] " + e.getMessage());
        }
        return decrypted;
    }

    public static String bytesToHex(byte[] data)
    {
        if (data==null) {
            return null;
        }
        int len = data.length;
        String str = "";
        for (int i=0; i<len; i++) {
            if ((data[i]&0xFF)<16) {
                str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
            }
            else {
                str = str + java.lang.Integer.toHexString(data[i]&0xFF);
            }
        }
        return str;
    }

    public static byte[] hexToBytes(String str) {
        if (str==null) {
            return null;
        }
        else if (str.length() < 2) {
            return null;
        }
        else {
            int len = str.length() / 2;
            byte[] buffer = new byte[len];
            for (int i=0; i<len; i++) {
                buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
            }
            return buffer;
        }
    }
}

PHP:

<?php

class ApiCrypter
{
    private $iv = '0000000000000000';
    private $key;// = '89432hjfsd891787';

    public function __construct($keyy)
    {
        $this->key = $keyy;
    }

    public function encrypt($str)
    {
        $encrypted = openssl_encrypt($str, 'AES-128-CBC', $this->key, 0, $this->iv);//
        return bin2hex($encrypted);

    }

    public function decrypt($code)
    {
        $code = $this->hex2bin($code);
        $decrypted = openssl_decrypt($code, 'AES-128-CBC', $this->key, 0, $this->iv);
        $ut = utf8_encode(trim($decrypted));
        //  return $this->pkcs5_unpad($ut);
        return $ut;
    }

    protected function hex2bin($hexdata)
    {
        $bindata = '';
        for ($i = 0; $i < strlen($hexdata); $i += 2) {
            $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
        }
        return $bindata;
    }

    protected function pkcs5_pad($text)
    {
        $blocksize = 16;
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    protected 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);
    }
}
?>

生成密钥(作为AES密钥),通过AES密钥加密明文(名称),加密AES密钥,并准备将它们发送到PHP:

SecureRandom secureRandom = new SecureRandom();
KeyGenerator keyGenerator;
keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256, secureRandom);
SecretKey key = keyGenerator.generateKey();

secret_key = key.getEncoded();
Byte[] encodedSessionKey = RSA.encryptByPublicKey(secret_key, public_key);

ApiCrypter apiCrypter=new ApiCrypter(encodedSessionKey);
String encryptedName = ApiCrypter.bytesToHex(apiCrypter.encrypt(nameStr));

String encodedStr = Base64.encodeToString(encodedSessionKey, Base64.DEFAULT);
AsyncDataClass asyncRequestObject = new AsyncDataClass();
asyncRequestObject.execute(serverUrl,encodedStr,encryptedName);

PHP 代码,用于使用 RSA 私钥解密 AES 密钥,并通过解密的 AES 密钥解密 NameString:

$encodedStr = "";
$encryptedName = "";

if(isset($_POST['encodedStr'])){
    $encodedSecretKey = $_POST['encodedStr'];
}

if(isset($_POST['encryptedName'])){
    $encryptedName = $_POST['encryptedName'];
}


$rsa = new \phpseclib\Crypt\RSA();
$rsa->setHash('sha1');
$rsa->setMGFHash('sha1');
$rsa->setEncryptionMode(1);
$rsa->loadKey(file_get_contents('private.key')); // RSA Private key


$AES_session_key = $rsa->decrypt(base64_decode($encodedSecretKey));

$ApiCrypter= new ApiCrypter($AES_session_key);
$decryptedName = $ApiCrypter->decrypt($encryptedName);

>

  • 这些类是否相互匹配?

    如何加密明文Java使用AES_Key(或在Java生成的密钥的副本)?

    如何使用AES_key(由RSA私钥解密)在PHP中解密明文?

  • 共有1个答案

    邢卓
    2023-03-14

    密钥由随机字节组成。这意味着,无论使用何种编码,某些字节都无法打印。要将字节表示为文本,通常使用十六进制或base64编码。这两者之间的区别在于,普通人可以从十六进制数字中找出字节值,而base64更有效(因为它使用更多的字符,因此每个字符可以编码6位,而十六进制数字每个字符只能编码4位)。

    在 Java 8 中,默认情况下仅支持 base 64:

    System.out.println(Base64.getEncoder().encodeToString(secretKey.getEncoded()));
    

    对于Android:

    Base64.encodeToString(secretKey.getEncoded(),Base64.DEFAULT);
    

    应该工作正常(对于< code>SecretKeySpec也是如此,因为它实现了< code>SecretKey)。

    当然,发送未受保护的密钥应该在安全的环境中执行,并且通常应该不惜一切代价避免。

     类似资料:
    • 我想从php发送post请求到python并得到答案,我写了这个脚本发送post 我使用定制python服务器

    • 问题内容: 我正在执行一个Android程序,该程序应该将数据从平板电脑发送到PHP Web服务。发送JSON的代码: PHP Web服务: 我尝试了获取JSON的不同方法,但没有一个对我有用。也许StackOverflow的优秀人才可以帮助我解决这个问题,因为他们总是遇到我遇到的其他所有问题。 问题答案: 在注释部分,您似乎只希望将JSON发送到您的PHP脚本。通常,您将POST发布到PHP,然

    • 问题内容: 我想以json格式向php发送一些数据,并在php中进行一些操作。我的问题是我无法通过Ajax将json数据发送到我的php文件。请帮助我该怎么做。我已经尝试过这种方式.. 在PHP中,我使用: 在php文件中添加print_r($ _ POST)时,它在firebug中显示array(0){}。 问题答案: 输了。您没有将JSON发送到服务器,而是发送了普通的POST查询(恰好包含J

    • 问题内容: 我的问题是可以使用ajax(jquery)将图像上传到服务器吗 以下是我的ajax脚本,无需重新加载页面即可发送文本 是否可以修改它以发送图像? 问题答案: 这可行。 是您要找的东西吗?

    • 问题内容: 什么是场景 我想从Android向服务器发送多个ArrayList(通常为5个),并将其插入到mysql数据库中。 我成功完成的工作 我已使用JSON成功将Android中的单个值和多个值发送到PHP脚本 我已经使用JSON从mysql数据库到android接收了单条记录和多条记录 这是用于从服务器插入值并从中获取价值的代码 和TeacherAuthen.php脚本 我被困在那里 我没

    • 问题内容: 我有一个生成图像的Java Applet。最终,我想将图像数据插入数据库中,因此我想将图像数据临时存储在包含小程序的页面上的表单字段中。我希望在不将图像文件存储在客户端计算机上的情况下执行此操作。 所有这些都来自签名板。这是一些应该从sigObj对象中存储的矢量数据生成位图图像的代码: image变量是BufferedImage对象。另外,如果我只是将图像变量发送回我的JavaScri