我的bb10应用已发送3DES-ECB
- 加密数据到后端(PHP)
PHP后端
public static function encrypt3Des($data, $key)
{
//Generate a key from a hash
$key = md5(utf8_encode($key), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
//Pad for PKCS7
$blockSize = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = $blockSize - ($len % $blockSize);
$data = $data.str_repeat(chr($pad), $pad);
//Encrypt data
$encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
return base64_encode($encData);
}
public static function decrypt3Des($data, $secret)
{
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
$data = base64_decode($data);
$data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
$block = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = ord($data[$len-1]);
return substr($data, 0, strlen($data) - $pad);
}
Blackberry 10客户端
/// cipherservice.hpp ///
#pragma once
#include <QObject>
#include <hudes.h>
#include <hugse56.h>
class CipherService : public QObject {
Q_OBJECT
public:
virtual ~CipherService();
CipherService(QString key);
QString encryptTDES(QString message);
QString decryptTDES(QString message);
private:
void initCipher(QString key);
void destroyCipher();
sb_GlobalCtx huGlobalContext;
sb_Context huContext;
sb_Key huKey;
sb_Params huParams;
};
/// cipherservice.cpp ///
#include "cipherservice.hpp"
#include <huctx.h>
#define TO_HEXSTR(code) ("0x" + QString("%1").arg(code, 0, 16).toUpper())
CipherService::CipherService(QString key)
: QObject() {
initCipher(key);
}
CipherService::~CipherService() {
destroyCipher();
}
void CipherService::initCipher(QString key) {
int rc = hu_GlobalCtxCreateDefault(&huGlobalContext);
LOGD << "hu_GlobalCtxCreateDefault return code = " << TO_HEXSTR(rc);
rc = hu_RegisterSbg56DES(huGlobalContext);
LOGD << "hu_RegisterSbg56DES return code = " << TO_HEXSTR(rc);
rc = hu_InitSbg56(huGlobalContext);
LOGD << "hu_InitSbg56 return code = " << TO_HEXSTR(rc) << " (0xF00D means already initialized so ignore it)";
rc = hu_DESParamsCreate(USED_SB_DES, SB_DES_ECB, SB_DES_PARITY_OFF, SB_DES_WEAK_KEY_OFF,
NULL, NULL, &huParams, huGlobalContext);
LOGD << "hu_DESParamsCreate return code = " << TO_HEXSTR(rc);
QByteArray resultKey = QCryptographicHash::hash(key.toUtf8().constData(), QCryptographicHash::Md5);
resultKey.append(resultKey.mid(0, 8));
LOGD << "key=" << resultKey.toBase64();
unsigned char* keyBuf = reinterpret_cast<unsigned char*>(resultKey.data());
size_t keyBufLen = SB_DES_KEY_SIZE;
rc = hu_DESKeySet(huParams, keyBufLen, keyBuf, keyBufLen, keyBuf, keyBufLen, keyBuf, &huKey, huGlobalContext);
LOGD << "hu_DESKeySet return code = " << TO_HEXSTR(rc);
const unsigned char iv[SB_DES_IV_SIZE] = {0};
rc = hu_DESBeginV2(huParams, huKey, SB_DES_ECB, SB_DES_IV_SIZE, iv, &huContext, huGlobalContext);
LOGD << "hu_DESBeginV2 return code = " << TO_HEXSTR(rc);
}
void CipherService::destroyCipher() {
if (&huContext != NULL) {
int rc = hu_DESEnd(&huContext, huGlobalContext);
LOGD << "hu_DESEnd return code = " << TO_HEXSTR(rc);
huContext = NULL;
}
}
QString CipherService::encryptTDES(QString msg) {
size_t pad = SB_DES_BLOCK_SIZE - (msg.length() % SB_DES_BLOCK_SIZE);
for (uint i = 0; i < pad; i += 1) {
msg.append(static_cast<QChar>(pad));
}
QByteArray plainBuf(msg.toUtf8());
char* cipherBuf = new char[plainBuf.length()];
LOGD << "hu_DESEncryptMsg plainBuf = " << plainBuf;
int rc = hu_DESEncrypt(huContext,
plainBuf.length(),
reinterpret_cast<const unsigned char*>(plainBuf.data()),
reinterpret_cast<unsigned char*>(cipherBuf), huGlobalContext);
QByteArray byteData((char*)cipherBuf, plainBuf.length());
QString result(byteData.toBase64());
LOGD << "hu_DESEncryptMsg length = " << plainBuf.length() << " code = " << TO_HEXSTR(rc) << " result = " << result;
return result;
}
QString CipherService::decryptTDES(QString msg) {
QByteArray cipherBuf(QByteArray::fromBase64(msg.toUtf8()));
if (cipherBuf.size() % SB_DES_BLOCK_SIZE) {
cipherBuf.resize((cipherBuf.size() / SB_DES_BLOCK_SIZE) * (SB_DES_BLOCK_SIZE));
}
LOGD << "hu_DESEncryptMsg cipherBuf = " << msg << " length = " << cipherBuf.length();
unsigned char* plainBuf = new unsigned char[cipherBuf.length() + 1](); // +1 to last \0
int rc = hu_DESDecrypt(huContext,
cipherBuf.length(),
reinterpret_cast<const unsigned char*>(cipherBuf.data()),
reinterpret_cast<unsigned char*>(plainBuf), huGlobalContext);
QByteArray byteData((char*)plainBuf, cipherBuf.length());
QString result(byteData);
if (result.length() > 0) {
size_t pad = (size_t) result[result.length() - 1].toAscii();
result = result.remove(result.length() - pad, pad);
}
LOGD << "hu_DESDecryptMsg length = " << cipherBuf.length() << " code = " << TO_HEXSTR(rc) << " result = " << result;
return result;
}
此解决方案不起作用,在故障排除期间,我发现PHP和BB10实现之间存在两个主要差异:
IV
,我不知道为什么因为ECB
模式不需要它,但我无法通过NULL
,因为我会收到错误代码openssl
,但它的API看起来非常有限,是否可以在BB10上使用3DES-ECB
实施openssl
?答案 0 :(得分:0)
问题是关键。 BB创建了24字节的3DES密钥,如下所示:
QByteArray resultKey = QCryptographicHash::hash(key.toUtf8().constData(), QCryptographicHash::Md5);
resultKey.append(resultKey.mid(0, 8));
它是key
这是一个字符串,通过MD%创建16字节。然后它将MD5输出的前8个字节附加到它。这会创建一个24字节的密钥,即所谓的双密钥3DES,这不安全且应该使用。
对于PHP,您需要以相同的方式创建密钥。
还要注意IV和填充。如上所述,ECB模式不使用IV,我已经一次又一次地看到pan IV被提供ECB模式,=通常是因为开发人员不了解ECB模式。
你最好在PHP中使用OpenSSL,mcrypt很糟糕。
使用一些十六进制打印来验证加密前密钥和IV是否相同。