【发布时间】: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 包括设置... 我怎样才能做到这一点??
【问题讨论】:
-
同一个用户,相似的代码,同样的问题:stackoverflow.com/questions/23271602/…
-
有一些变化
-
但你还是犯了同样的错误。
标签: java c++ encryption