C++ 如何在WinRT中加密和解密常量字符*

C++ 如何在WinRT中加密和解密常量字符*,c++,windows-runtime,c++-cx,C++,Windows Runtime,C++ Cx,我一直在尝试编写加密和解密函数,其签名要求输入和输出字符串仅为void*type。如果输入可以指定为IBuffer^,但在另一种情况下,源字符串和加密->解密字符串不匹配,则代码工作正常 CodeIBuffer^ byteArrayToIBufferPtr(byte *source, int size) { Platform::ArrayReference<uint8> blobArray(source, size); IBuffer ^buffer = Crypto

我一直在尝试编写加密和解密函数,其签名要求输入和输出字符串仅为
void*
type。如果输入可以指定为
IBuffer^
,但在另一种情况下,源字符串和加密->解密字符串不匹配,则代码工作正常

CodeIBuffer^ byteArrayToIBufferPtr(byte *source, int size)
{
    Platform::ArrayReference<uint8> blobArray(source, size);
    IBuffer ^buffer = CryptographicBuffer::CreateFromByteArray(blobArray);
    return buffer;
}

byte* IBufferPtrToByteArray(IBuffer ^buffer)
{
    Array<unsigned char,1U> ^platArray = ref new Array<unsigned char,1U>(256);
    CryptographicBuffer::CopyToByteArray(buffer,&platArray);

    byte *dest = platArray->Data;
    return dest;
}

int DataEncryption::encryptData(EncryptionAlgorithm algo, int keySize, void* srcData, const unsigned int srcSize,
        void*& encData, unsigned int& encSize)
{

    LOG_D(TAG, "encryptData()");

    if(srcData == nullptr)
    {
        LOG_E(TAG,"");
        return DataEncryption::RESULT_EMPTY_DATA_ERROR;
    }
    if(srcSize == 0)
    {
        LOG_E(TAG,"");
        return DataEncryption::RESULT_SIZE_ZERO_ERROR;
    }

    IBuffer^ encrypted;
    IBuffer^ buffer;
    IBuffer^ iv = nullptr;
    String^ algName;
    bool cbc = false;

    switch (algo)
    {
    case DataEncryption::ENC_DEFAULT:
        algName = "AES_CBC";
        cbc = true;
        break;
    default:
        break;
    }

    // Open the algorithm provider for the algorithm specified on input.
    SymmetricKeyAlgorithmProvider^ Algorithm = SymmetricKeyAlgorithmProvider::OpenAlgorithm(algName);

    // Generate a symmetric key.
    IBuffer^ keymaterial = CryptographicBuffer::GenerateRandom((keySize + 7) / 8);
    CryptographicKey^ key;

    try
    {
        key = Algorithm->CreateSymmetricKey(keymaterial);
    }
    catch(InvalidArgumentException^ e)
    {
        LOG_E(TAG,"encryptData(): Could not create key.");
        return DataEncryption::RESULT_ERROR;
    }

    // CBC mode needs Initialization vector, here just random data.
    // IV property will be set on "Encrypted".
    if (cbc)
        iv = CryptographicBuffer::GenerateRandom(Algorithm->BlockLength);

    // Set the data to encrypt. 
    IBuffer ^srcDataBuffer = byteArrayToIBufferPtr(static_cast<byte*>(srcData),256);

    // Encrypt and create an authenticated tag.
    encrypted = CryptographicEngine::Encrypt(key, srcDataBuffer, iv);

    //encData = encrypted;
    byte *bb = IBufferPtrToByteArray(encrypted);
    encData = IBufferPtrToByteArray(encrypted);
    encSize = encrypted->Length;

    return DataEncryption::RESULT_SUCCESS;
}


int DataEncryption::decryptData(EncryptionAlgorithm algo, int keySize, void* encData, const unsigned int encSize,
        void*& decData, unsigned int& decSize)
{
    LOG_D(TAG, "decryptData()");

    if(encData == nullptr)
    {
        LOG_E(TAG,"");
        return DataEncryption::RESULT_EMPTY_DATA_ERROR;
    }
    if(encSize == 0)
    {
        LOG_E(TAG,"");
        return DataEncryption::RESULT_SIZE_ZERO_ERROR;
    }

    IBuffer^ encrypted;
    IBuffer^ decrypted;
    IBuffer^ iv = nullptr;
    String^ algName;
    bool cbc = false;

    switch (algo)
    {
    case DataEncryption::ENC_DEFAULT:
        algName = "AES_CBC";
        cbc = true;
        break;
    default:
        break;
    }

    // Open the algorithm provider for the algorithm specified on input.
    SymmetricKeyAlgorithmProvider^ Algorithm = SymmetricKeyAlgorithmProvider::OpenAlgorithm(algName);

    // Generate a symmetric key.
    IBuffer^ keymaterial = CryptographicBuffer::GenerateRandom((keySize + 7) / 8);
    CryptographicKey^ key;

    try
    {
        key = Algorithm->CreateSymmetricKey(keymaterial);
    }
    catch(InvalidArgumentException^ e)
    {
        LOG_E(TAG,"encryptData(): Could not create key.");
        return DataEncryption::RESULT_ERROR;
    }

    // CBC mode needs Initialization vector, here just random data.
    // IV property will be set on "Encrypted".
    if (cbc)
        iv = CryptographicBuffer::GenerateRandom(Algorithm->BlockLength);

    // Set the data to decrypt. 
    byte *cc = static_cast<byte*>(encData);
    IBuffer ^encDataBuffer = byteArrayToIBufferPtr(cc,256);
    // Decrypt and verify the authenticated tag.
    decrypted = CryptographicEngine::Decrypt(key, encDataBuffer, iv);

    byte *bb = IBufferPtrToByteArray(decrypted);
    decData = IBufferPtrToByteArray(decrypted);

    decSize = decrypted->Length;

    return DataEncryption::RESULT_SUCCESS;
}
codebuffer^ByteArrayToibuffer(字节*源,整数大小)
{
平台::ArrayReference blobArray(源、大小);
IBuffer^buffer=加密缓冲区::CreateFromByteArray(blobArray);
返回缓冲区;
}
字节*IBuffer^BufferToByteArray(IBuffer^buffer)
{
数组^platArray=ref新数组(256);
CryptographicBuffer::CopyToByteArray(缓冲区和平台阵列);
字节*dest=platArray->Data;
返回目的地;
}
int DataEncryption::encryptData(EncryptionAlgorithm算法,int keySize,void*srcData,const unsigned int srcSize,
void*&encData,unsigned int&encSize)
{
日志(标记“encryptData()”);
if(srcData==nullptr)
{
日志(标签“”);
返回DataEncryption::RESULT\u EMPTY\u DATA\u错误;
}
如果(srcSize==0)
{
日志(标签“”);
返回DataEncryption::结果\大小\零\错误;
}
IBuffer^加密;
伊布弗缓冲液;
IBuffer^iv=空PTR;
字符串^algName;
bool cbc=假;
开关(algo)
{
案例数据加密::ENC_默认值:
algName=“AES_CBC”;
cbc=真;
打破
违约:
打破
}
//为输入中指定的算法打开算法提供程序。
SymmetricKeyAlgorithmProvider^算法=SymmetricKeyAlgorithmProvider::OpenAlgorithm(algName);
//生成对称密钥。
IBuffer^keymaterial=CryptographicBuffer::GeneratorDOM((keySize+7)/8);
加密密钥^密钥;
尝试
{
key=算法->CreateSymmetricKey(keymaterial);
}
捕获(InvalidArgumentException ^e)
{
日志(标记“encryptData():无法创建密钥”);
返回DataEncryption::RESULT\u错误;
}
//CBC模式需要初始化向量,这里只是随机数据。
//IV属性将设置为“加密”。
国际单项体育联合会(cbc)
iv=加密缓冲区::生成域(算法->块长度);
//将数据设置为加密。
IBuffer^srcDataBuffer=bytearraytibuffer(静态转换(srcData),256);
//加密并创建经过身份验证的标记。
加密=加密引擎::加密(密钥,srcDataBuffer,iv);
//加密数据=加密;
字节*bb=IBuffertToByteArray(加密);
encData=IBufferToByteArray(加密);
encSize=加密->长度;
返回DataEncryption::RESULT\u SUCCESS;
}
int DataEncryption::decryptData(EncryptionAlgorithm algo,int keySize,void*encData,const unsigned int encSize,
void*&decData,unsigned int&decSize)
{
日志(标记“decryptData()”);
如果(encData==nullptr)
{
日志(标签“”);
返回DataEncryption::RESULT\u EMPTY\u DATA\u错误;
}
如果(encSize==0)
{
日志(标签“”);
返回DataEncryption::结果\大小\零\错误;
}
IBuffer^加密;
伊布弗^解密;
IBuffer^iv=空PTR;
字符串^algName;
bool cbc=假;
开关(algo)
{
案例数据加密::ENC_默认值:
algName=“AES_CBC”;
cbc=真;
打破
违约:
打破
}
//为输入中指定的算法打开算法提供程序。
SymmetricKeyAlgorithmProvider^算法=SymmetricKeyAlgorithmProvider::OpenAlgorithm(algName);
//生成对称密钥。
IBuffer^keymaterial=CryptographicBuffer::GeneratorDOM((keySize+7)/8);
加密密钥^密钥;
尝试
{
key=算法->CreateSymmetricKey(keymaterial);
}
捕获(InvalidArgumentException ^e)
{
日志(标记“encryptData():无法创建密钥”);
返回DataEncryption::RESULT\u错误;
}
//CBC模式需要初始化向量,这里只是随机数据。
//IV属性将设置为“加密”。
国际单项体育联合会(cbc)
iv=加密缓冲区::生成域(算法->块长度);
//设置要解密的数据。
字节*cc=静态_转换(encData);
IBuffer^encDataBuffer=bytearraytibuffer(cc,256);
//解密并验证已验证的标记。
解密=加密引擎::解密(密钥,encDataBuffer,iv);
字节*bb=IBuffertToByteArray(已解密);
decData=ibuffertortobytearray(已解密);
decSize=解密->长度;
返回DataEncryption::RESULT\u SUCCESS;
}

我猜问题出在这个函数上:

byte* IBufferPtrToByteArray(IBuffer ^buffer)
{
    Array<unsigned char,1U> ^platArray = ref new Array<unsigned char,1U>(256);
    CryptographicBuffer::CopyToByteArray(buffer,&platArray);

    byte *dest = platArray->Data;
    return dest;
}
步骤如下:

  • 创建与
    std::string
    中的字节对应的
    ArrayReference
    (无复制)
  • 将其传递到
    cryptographicsbuffer::CreateFromByteArray()
    以获取您的
    IBuffer^
    。仍然没有复制数据
  • 调用hash/encryption函数,传递刚刚创建的
    IBuffer^
    。作为回报,您将得到另一个
    IBuffer^
    ,它可能使用也可能不使用完全相同的存储(我认为这实际上取决于算法的实现)
  • 创建类型为
    Array^
    的变量。不要分配对象,您将通过引用获得一个对象
  • 将该对象的地址传递到
    CryptographicBuffer::CopyToByteArray()
    以接收密钥数据的副本
  • 数组^
    保持有效时,将其字节复制到本机数组中

  • 加密。相当复杂的领域。你使用什么加密方法?您正在创建自己的加密算法吗?您当前遇到的问题是否与加密有关?它只是一个C++语法/语义误用问题,可以不提“加密”这个词来解决吗?嗨,马克!我正在编写一个包装器来加密和解密加密库中已有的算法。以前我使用的是openssl第三方库;现在我
    using namespace ::Platform;
    using namespace ::Windows::Foundation::Cryptography;
    using namespace ::Windows::Foundation::Cryptography::Core;
    
    auto byteArray = ArrayReference<byte>(reinterpret_cast<byte*>(const_cast<char*>(str.data())), str.length());
    auto inBuf = CryptographicBuffer::CreateFromByteArray(byteArray);
    auto keyBuf = HashAlgorithmProvider::OpenAlgorithm(HashAlgorithmNames::Sha1)->HashData(inBuf);
    
    Array<byte>^ outArray = nullptr;
    CryptographicBuffer::CopyToByteArray(keyBuf, &outArray);
    memcpy_s(_key, KeySize, outArray->Data, outArray->Length);