用Java加密字符串并用C++解密.crypto++

Encrypting a string in Java and decrypting it in C++. crypto++

本文关键字:C++ 解密 crypto++ 串并 字符串 Java 加密 字符      更新时间:2023-10-16

我需要用Java加密字符串,然后用C++解密。我看到C++有一个Crypto++库,Java有JCE。算法为AES/EBC/NOADDING字符串是"12345690123456",用于java中的noadding问题。密钥为byte[]密钥=新的byte[]{0x00,0x00;16字节。这些条件在java和c++中是相同的。

下面是java代码。

import javax.crypto.*;
import javax.crypto.spec.*;
public class etest {  
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        encryp ec=new encryp();
        String name="1234567890123456";
        System.out.println(name);
        try {
            System.out.println(ec.encrypt(name));
//          System.out.println(ec.decrypt(ec.encrypt(name)));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
class encryp {
//  public static String key = "abcdefgh12345678";
    static byte []key=new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    public static String encrypt(String message) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/NOPADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(message.getBytes());
        return byteArrayToHex(encrypted);
//      return encrypted;
    }
    public static String decrypt(String encrypted) throws Exception {
        // use key coss2
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] original = cipher.doFinal(hexToByteArray(encrypted));
        String originalString = new String(original);
        return originalString;
    }
    public static byte[] hexToByteArray(String hex) {
        if (hex == null || hex.length() == 0) {
            return null;
        }
        byte[] ba = new byte[hex.length() / 2];
        for (int i = 0; i < ba.length; i++) {
            ba[i] = (byte) Integer
                    .parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }
        return ba;
    }
    /**
     * 
     * @param ba
     *            byte[]
     * @return
     */
    public static String byteArrayToHex(byte[] ba) {
        if (ba == null || ba.length == 0) {
            return null;
        }
        StringBuffer sb = new StringBuffer(ba.length * 2);
        String hexNumber;
        for (int x = 0; x < ba.length; x++) {
            hexNumber = "0" + Integer.toHexString(0xff & ba[x]);
            sb.append(hexNumber.substring(hexNumber.length() - 2));
        }
        return sb.toString();
    }
}

接下来是c++代码。

#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1   
// Crypto++ Includes
#include "cryptopp562cryptlib.h"
#include "cryptopp562osrng.h" 
#include "cryptopp562hex.h"
#include "cryptopp562Base64.h"
#include "cryptopp562aes.h"        
#include "cryptopp562seed.h"
#include "cryptopp562des.h"
#include "cryptopp562modes.h"      
#include "cryptopp562filters.h"    
#include <iostream>
#ifdef _DEBUG
#  pragma comment ( lib, "cryptlibd" )
#else
#  pragma comment ( lib, "cryptlib" )
#endif
template <class TyMode>
std::string Encrypt(TyMode &Encryptor, const std::string &PlainText)
{
    std::string EncodedText;
    try {
        CryptoPP::StringSource( PlainText, true,
            new CryptoPP::StreamTransformationFilter(Encryptor, 
                new CryptoPP::Base64Encoder(
                    new CryptoPP::StringSink( EncodedText ), false
                    ), CryptoPP::BlockPaddingSchemeDef::NO_PADDING
            )
        ); 
    }
    catch (...) {}
    return EncodedText;
}
template <class TyMode>
std::string Decrypt(TyMode &Decryptor, const std::string &EncodedText)
{
    std::string RecoveredText;
    try {
        CryptoPP::StringSource( EncodedText, true,
            new CryptoPP::Base64Decoder(
                new CryptoPP::StreamTransformationFilter( Decryptor,
                    new CryptoPP::StringSink( RecoveredText ), 
                    CryptoPP::BlockPaddingSchemeDef::NO_PADDING
                ) 
            ) 
        ); 
    }
    catch (...) {}
    return RecoveredText;
}
template <class Ty>
std::string CBC_Encrypt(byte *KEY, byte *IV, const std::string &PlainText)
{
    CryptoPP::CBC_Mode<typename Ty>::Encryption Encryptor(KEY, typename Ty::DEFAULT_KEYLENGTH, IV);
    return Encrypt(Encryptor, PlainText);
}

template <class Ty>
std::string CBC_Decrypt(byte *KEY, byte *IV, const std::string &PlainText)
{
    CryptoPP::CBC_Mode<typename Ty>::Decryption Decryptor(KEY, typename Ty::DEFAULT_KEYLENGTH, IV);
    return Decrypt(Decryptor, PlainText);
}
template <class Ty>
std::string ECB_Encrypt(byte *KEY, const std::string &PlainText)
{
    CryptoPP::ECB_Mode<typename Ty>::Encryption Encryptor(KEY, typename Ty::DEFAULT_KEYLENGTH);
    return Encrypt(Encryptor, PlainText);
}

template <class Ty>
std::string ECB_Decrypt(byte *KEY, const std::string &PlainText)
{
    CryptoPP::ECB_Mode<typename Ty>::Decryption Decryptor(KEY, typename Ty::DEFAULT_KEYLENGTH);
    return Decrypt(Decryptor, PlainText);
}

template <class CryptoType>
void Test()
{
    using namespace std;
    const std::string sText = "1234567890123456";
    std::string sEnc, sDec;
    byte KEY[ 16 ] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//  byte KEY[ CryptoType::DEFAULT_KEYLENGTH ] = {0, }; 
    byte IV[ CryptoType::BLOCKSIZE ] = {0x01, }; 

    sEnc = CBC_Encrypt<CryptoType>(KEY, IV, sText);
    sDec = CBC_Decrypt<CryptoType>(KEY, IV, sEnc);
//  cout << CryptoType::StaticAlgorithmName() << " : " << "CBC_MODE" << endl;
//  cout << sText << "n -> " << sEnc << "n -> " << sDec << endl;

    // ECB 
    sEnc = ECB_Encrypt<CryptoType>(KEY, sText);
//  sEnc="41f813eca9ddd189f7ff3280ada72c8a";
    sDec = ECB_Decrypt<CryptoType>(KEY, sEnc);
    cout << CryptoType::StaticAlgorithmName() << " : " << "ECB_MODE" << endl;
    cout << sText ;
    cout<<hex<< "n -> " << sEnc << "n -> " << sDec << endl;
    cout << endl;
}

int main()
{
    using namespace std;
    // SEED
//  Test<CryptoPP::SEED>();
    // AES 
    Test<CryptoPP::AES>();
    // DES 
//  Test<CryptoPP::DES>();
    system("pause");
    return 0;
}

c++的结果可能是经过编码的。但解码后的密文和java加密的结果也不一样。当然,我想到的是java中的十六进制字符串。然而,十六进制、二进制等编码或解码都不相同
我希望这个工作顺利。什么是问题?帮助plz

+我搜索过http://www.example-code.com/vcpp/aes_javaJceAesCbc.asp图书馆。这个效果好吗?我设置了环境并运行,但lnk2019错误。。。我想我设置对了Lib,h包括设置。。。我该怎么做??

我必须查看加密代码才能确定,但我希望它适用于实际的数据图像,而不是字符。和"1234567890123456"的实际数据图像非常不同在Java String(其中每个字符是16位)和C++std::string(其中每个字符至少总共为8位但最奇特的机器)。