在 Java 中加密字符串并在 C++ 中解密。加密++

Posted

技术标签:

【中文标题】在 Java 中加密字符串并在 C++ 中解密。加密++【英文标题】:Encrypting a string in Java and decrypting it in C++. crypto++ 【发布时间】:2014-04-25 11:03:08 【问题描述】:

我需要在 Java 中加密一个字符串并在 C++ 中解密它。我见过 C++ 有一个 Crypto++ 库,Java 有 JCE。 算法是 AES/ECB/NOPADDING 对于 java 中的 nopadding 问题,字符串是“12345690123456”。 密钥为 byte []key=new byte[]0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 "cryptopp562\cryptlib.h"
#include "cryptopp562\osrng.h" 
#include "cryptopp562\hex.h"
#include "cryptopp562\Base64.h"
#include "cryptopp562\aes.h"        
#include "cryptopp562\seed.h"
#include "cryptopp562\des.h"
#include "cryptopp562\modes.h"      
#include "cryptopp562\filters.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中的十六进制字符串。然而,十六进制、二进制等编码或解码都不尽相同。 我希望这能很好地工作。 什么是问题?请帮忙

+ 我搜索了http://www.example-code.com/vcpp/aes_javaJceAesCbc.asp 图书馆。 这个效果好吗? 我设置环境并运行但 lnk2019 错误... 我以为我设置了正确的 Lib,h 包括设置... 我怎样才能做到这一点??

【问题讨论】:

同一个用户,相似的代码,同样的问题:***.com/questions/23271602/… 有一些变化 但你还是犯了同样的错误。 【参考方案1】:

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

【讨论】:

感谢您的评论。那么如果我测试,我如何输入纯文本? @user3489182 计算机中没有“纯文本”之类的东西; text 总是有一个内部表示,然后通过其编码进行修改。您必须将字符串转换为规范形式,可能是 Java 中的 ByteBuffer,然后对其进行加密。 (事实上​​,C++ std::string 使用 char 作为底层类型意味着您可能能够直接使用它。

以上是关于在 Java 中加密字符串并在 C++ 中解密。加密++的主要内容,如果未能解决你的问题,请参考以下文章

CryptoJS和Java进行加解密

在 node 中加密并在 java 中解密

android中使用jni对字符串加解密实现分析

如何在shell中加密和解密字符串/文本(linux环境)

在 PHP 中加密字符串并在 Node.js 中解密

加解密 Java 凯撒密码