AES-256-CBC PKCS7填充从PHP连接到.net服务器



我需要加密用户和密码与AES-256-CBC和PKCS7填充连接到一个。net服务器应用程序,它不是我的。

首先,我使用Diffie-Hellman算法获得公共服务器密钥,按照本网站的说明:

https://doc.developer.milestonesys.com/mipsdkmobile/index.html?base=content_0.html&树= tree_home.html

从服务器获取公钥的代码如下:

private const DH_PRIME = 'F488FD584E49DBCD20B49DE49107366B336C380D451D0F7C88B31C7C5B2D8EF6F3C923C043F0A55B188D8EBB558CB85D38D334FD7C175743A31D186CDE33212CB52AFF3CE1B1294018118D7C84A70A72D686C40319C807297ACA950CD9969FABD00A509B0246D3083D66A45D419F9C7CBD894B221926BAABA25EC355E92F78C7';
private const DH_GENERATOR = '02';
$privateKey = gmp_init(uniqid(), 32);
$publicKey = gmp_powm(self::DH_GENERATOR, $privateKey, base_convert( self::DH_PRIME, 16,10));

一旦我得到了密钥,所以它在这里工作得很好,我必须用我的私钥计算服务器密钥,之前解码base64服务器密钥,并将其从二进制转换为十六进制:

// Decode server public returned key (encoded in base 64)
$serverPKBase64Decoded = base64_decode($apiResponse['response']['Command']['OutputParams']['Param']['7']['@attributes']['Value']);
$serverPublicKey16 = bin2hex($serverPKBase64Decoded);
// Calculate shared key
$prime = gmp_init(self::DH_PRIME,16);
$serverPk = gmp_init($serverPublicKey, 16);
$localPk = gmp_init($localPrivateKey,32);
$sharedKey = gmp_powm($serverPk, $localPk, $prime);
// Get shared key as hexadecimal value
$sharedKeyHex = gmp_strval($sharedKey, 16);

现在,是获得初始化向量(iv)和加密用户名和密码的密钥的部分:

$iv = substr($sharedKeyHex,0,16);
$key = strlen($sharedKeyHex)-32,32);
// Encrypt username and password
$encryptedUsername = base64_encode(openssl_encrypt($username,$cipher,$key,OPENSSL_RAW_DATA,$iv));
$encryptedPassword = base64_encode(openssl_encrypt($password,$cipher,$key,OPENSSL_RAW_DATA,$iv));

当我发送数据并得到响应时,它抛出一个错误16,文本为"不正确的公钥"。

我们提供者的SDK提供的例子(与CryptoJS JS)登录过程是等价的。请确认JS中的代码与PHP中的代码是相等的:

JS代码:

/**
* Encode a string using client and server public keys
* 
* @param       str         string      String to encode
* @access                  public
* @return                  string      Base64 encoded encrypted string
*/
this.encodeString = function(str) {
var secretString = this._sharedKey || this.getSharedKey().substring(0, 96);
var key = CryptoJS.enc.Hex.parse(secretString.substring(32, 96)); 
var iv = CryptoJS.enc.Hex.parse( secretString.substring(0,32) ); 

var params = { 'iv': iv };
if (XPMobileSDKSettings.defaultEncryptionPadding && CryptoJS.pad[XPMobileSDKSettings.defaultEncryptionPadding]) {
params.padding = CryptoJS.pad[XPMobileSDKSettings.defaultEncryptionPadding];
}
return CryptoJS.AES.encrypt(str, key, params).ciphertext.toString(CryptoJS.enc.Base64);
};

我已经测试了许多填料,但我不能让它工作。任何想法为什么它不工作或我必须改变它的工作?

你应该在你的用户名前加上& &;使用您自己的公钥密码,否则服务器无法计算共享密钥。

最新更新