BlackBerry 10, реализация 3DES-ECB

вступление

Мое приложение 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;
}

проблема

Это решение не работает, во время устранения неполадок я обнаружил 2 основных различия между реализациями PHP и BB10:

  • BB10 использует только 8-байтовые ключи, PHP использует 24-байтовые ключи
  • BB10 требуют IV и я не знаю почему, потому что ECB режим не требует, но я не могу пройти NULL потому что я получу код ошибки

Вопросы

  • Можно ли использовать разные длины клавиш на каскадах BlackBerry10?
  • Какая библиотека крипт используется там? Это из QNX?
  • Я видел, что есть openssl представлен на BB10, но его API выглядит очень ограниченным, возможно ли реализовать 3DES-ECB с openssl на BB10?

связи

0

Решение

Вопрос является ключевым. BB создает 24-байтовый ключ 3DES следующим образом:

QByteArray resultKey = QCryptographicHash::hash(key.toUtf8().constData(), QCryptographicHash::Md5);
resultKey.append(resultKey.mid(0, 8));

Это принимает key которая является строкой, забавляется через MD%, создавая 16 байтов. Затем он добавляет первые 8 байтов вывода MD5 к нему. Это создает 24-байтовый ключ, который называется 3DES с двумя ключами, это небезопасно и должно использоваться.

Для PHP вам нужно создать ключ таким же образом.

Также обратите внимание на IV и прокладку. Как уже отмечалось, в режиме ECB не используется IV, и я неоднократно видел, как панорамирование IV снабжается режимом ECB = в основном потому, что разработчики не понимали режим ECB.

Возможно, вам лучше использовать OpenSSL в PHP, mcrypt ужасен.

Используйте некоторые шестнадцатеричные отпечатки, чтобы убедиться, что ключ и IV совпадают до шифрования.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector