用java加密字符串并在C++中解密 我需要用java加密字符串,并用C++解密它。我看到C++有一个密码+库,java有JCE,Jasypt,PojCaskar等,但是我越来越困惑……
我在找一些简单的东西。此用例不需要高安全性。重要的是,一端的加密算法与另一端的加密算法类似,以最简单的方式配置它们 编辑改进的解释: 我想这样做: 在Java中:获取一个输入字符串,用字符串密码对其进行加密,而不是像字节数组或初始化向量这样的东西,从而获得一个加密字符串 在C++中:接收上述加密字符串,并使用与上述相同的字符串密码对其解密,获得原始输入字符串 对于Java部分,我知道Jasypt代码:用java加密字符串并在C++中解密 我需要用java加密字符串,并用C++解密它。我看到C++有一个密码+库,java有JCE,Jasypt,PojCaskar等,但是我越来越困惑……,java,c++,cryptography,encryption,Java,C++,Cryptography,Encryption,我在找一些简单的东西。此用例不需要高安全性。重要的是,一端的加密算法与另一端的加密算法类似,以最简单的方式配置它们 编辑改进的解释: 我想这样做: 在Java中:获取一个输入字符串,用字符串密码对其进行加密,而不是像字节数组或初始化向量这样的东西,从而获得一个加密字符串 在C++中:接收上述加密字符串,并使用与上述相同的字符串密码对其解密,获得原始输入字符串 对于Java部分,我知道Jasypt代码: StandardPBEStringEncryptor hexEncryptor = new S
StandardPBEStringEncryptor hexEncryptor = new StandardPBEStringEncryptor() ;
hexEncryptor.setStringOutputType("hexadecimal");
hexEncryptor.setPassword(ENCRYPTION_PASSWORD);
String encryptedString = hexEncryptor.encrypt(inputString);
这将是很好的,但我不知道它使用的WICH算法和C++中类似的解密它。
< P>首先:AES是块密码,即它对固定字节数的块加密或解密-通常为16。所以你需要像AES/CBC或AES/CTS这样的东西 对于C++,我不知道任何东西都比CyrPro ++。 用于Java和JCE 样本:import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.Key;
import java.text.NumberFormat;
public static void runEncTest( byte[] encryptionKey, byte[] ivBytes, byte[] input )
{
try
{
Key key = new SecretKeySpec( encryptionKey, "AES" );
Cipher cipher = Cipher.getInstance( "AES/CTS/NoPadding" );
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
printByteArray( "PLAIN:", input );
printByteArray( "CRYPT:", cipherText );
}
catch( java.lang.Exception e )
{
System.out.println("Got an Exception: " + e.getMessage());
}
}
首先:AES是一种分组密码,即它加密或解密固定字节数(通常为16)的块。所以你需要像AES/CBC或AES/CTS这样的东西 对于C++,我不知道任何东西都比CyrPro ++。 用于Java和JCE 样本:
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.Key;
import java.text.NumberFormat;
public static void runEncTest( byte[] encryptionKey, byte[] ivBytes, byte[] input )
{
try
{
Key key = new SecretKeySpec( encryptionKey, "AES" );
Cipher cipher = Cipher.getInstance( "AES/CTS/NoPadding" );
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
printByteArray( "PLAIN:", input );
printByteArray( "CRYPT:", cipherText );
}
catch( java.lang.Exception e )
{
System.out.println("Got an Exception: " + e.getMessage());
}
}
如果安全性不重要,只需在一端对其进行XOR,比如70,然后在另一端再次进行XOR。这将需要大约10分钟的时间,任何饼干,以了解手动。或者是一个擅长破解报纸上的密码的奶奶
如果您真的想要安全+简单且缓慢的处理,则无所谓如果安全性不重要,只需在一端对其进行异或运算,例如70,然后在另一端再次进行异或运算。这将需要大约10分钟的时间,任何饼干,以了解手动。或者是一个擅长破解报纸上的密码的奶奶
如果你真的想要安全+简单和缓慢的处理,你可以做到这一点,这不是一大堆工作。您只需要加密库中的构建块 使用PBKDF1或PBKDF2进行密钥派生。这两种算法在C++和java中都有很多实现。你输入一个密码,你就会得到一个对称的加密密钥 你说高安全性并不重要,我认为你要么有安全性,要么没有安全性,这没有多大意义,但让我抓住它,并认为这意味着你会满足于使用流密码,如RC4,而不是带有IVs和分组密码模式的AES等,这在各种实现中可能是一个难题 所以使用RC4,也就是ARC4。同样,在爪哇和C++中有许多实现。你给它输入你的密钥和一串字节,然后输出一串字节:基于操作的明文或密文。RC4并没有很好的声誉,但直到今天,它仍然是IE和IIS中TLS的默认密码。你对RC4没问题。我不是IE和IIS的粉丝有很多原因,但RC4不在我的名单上 为了更好地衡量,您可能希望在加密前为明文加上前缀,然后再加上标题。您可以将明文的长度放在标题中,然后SHA1/256/512获取明文的pick散列。同样,在C++和java中,这些散列ALGOS的许多很好的实现。然后加密头和明文。这样就很容易判断解密是否顺利;只需验证长度和散列字段 <> P>只要使用C++和java中相同的、完善的算法,并且定义了一个定义良好的交换格式,请参见上面的4,您可以快速安全地解决这个问题。 编辑: 注意,有一些适用于流密码的注意事项。引用施奈尔的话: 世界上最重要的规则之一 流密码永远不要使用 相同的密钥流加密两个 不同的文件。如果有人这样做, 您可以通过XORing来破坏加密 这两个密文流在一起。 密钥流退出,您就结束了 用明文与明文异或 -您可以使用字母频率轻松恢复这两个明文 分析和其他基本技术 这是一个业余的密码错误。这个 防止这种攻击的简单方法是 使用唯一的初始化向量 四、除钥匙外 您可以加密文档
你可以做到,这不是一大堆工作。您只需要加密库中的构建块 使用PBKDF1或PBKDF2进行密钥派生。这两种算法在C++和java中都有很多实现。你输入一个密码,你就会得到一个对称的加密密钥 你说高安全性并不重要,我认为你要么有安全性,要么没有安全性都没有意义,但让我抓住它,认为它意味着你会满足于使用 流密码(如RC4)代替AES,使用其IVs和分组密码模式等,这在各种实现中都是一个难题 所以使用RC4,也就是ARC4。同样,在爪哇和C++中有许多实现。你给它输入你的密钥和一串字节,然后输出一串字节:基于操作的明文或密文。RC4并没有很好的声誉,但直到今天,它仍然是IE和IIS中TLS的默认密码。你对RC4没问题。我不是IE和IIS的粉丝有很多原因,但RC4不在我的名单上 为了更好地衡量,您可能希望在加密前为明文加上前缀,然后再加上标题。您可以将明文的长度放在标题中,然后SHA1/256/512获取明文的pick散列。同样,在C++和java中,这些散列ALGOS的许多很好的实现。然后加密头和明文。这样就很容易判断解密是否顺利;只需验证长度和散列字段 <> P>只要使用C++和java中相同的、完善的算法,并且定义了一个定义良好的交换格式,请参见上面的4,您可以快速安全地解决这个问题。 编辑: 注意,有一些适用于流密码的注意事项。引用施奈尔的话: 世界上最重要的规则之一 流密码永远不要使用 相同的密钥流加密两个 不同的文件。如果有人这样做, 您可以通过XORing来破坏加密 这两个密文流在一起。 密钥流退出,您就结束了 用明文与明文异或 -您可以使用字母频率轻松恢复这两个明文 分析和其他基本技术 这是一个业余的密码错误。这个 防止这种攻击的简单方法是 使用唯一的初始化向量 四、除钥匙外 您可以加密文档
RSA加密是一种公钥加密,易于实现和使用 之前有一篇关于C++中RSA加密的stackoverflow帖子:
谷歌快速搜索Java RSA将为您提供足够的库来加密/解密以满足您的需要。RSA encryption是一种公钥加密,易于实现和使用 之前有一篇关于C++中RSA加密的stackoverflow帖子:
<>谷歌java RSA的快速搜索将为您提供足够的库来进行加密/解密。java/C++中的密码分析。在Java中,默认值是ECB。这可能是个问题。< P>分析C++和java中使用的密码。在Java中,默认值是ECB。这可能是个问题。我在互联网上对此进行了大量研究,但没有找到解决方案。所以我决定自己做 我创建了一个类来实现这一点!下面的代码自行解释。好看
#pragma once
#include <string>
#include "../../Include/Cryptopp562/aes.h"
using namespace CryptoPP;
//.h
class CryptoUtil
{
public:
CryptoUtil(std::wstring mac);
byte m_key[CryptoPP::AES::DEFAULT_KEYLENGTH];
byte m_iv[CryptoPP::AES::DEFAULT_KEYLENGTH];
char m_macInChar[12];
// decripty string encrypted in AES/CBC/PKCS5Padding mode
std::wstring DecryptStr(std::wstring str);
};
//.cpp
#include "stdafx.h"
#include "CryptoUtil.h"
#include <atlstr.h>
#include "../../Include/Cryptopp562/cryptlib.h"
#include "../../Include/Cryptopp562/filters.h"
#include "../../Include/Cryptopp562/modes.h"
#include "../../Include/Cryptopp562/modes.h"
#include "../../Include/Cryptopp562/aes.h"
#include "../../Include/Cryptopp562/filters.h"
#include "../../Include/Cryptopp562/aes.h"
#include "../../Include/Cryptopp562/base64.h"
#include "../../Include/Cryptopp562/md5.h"
using namespace CryptoPP;
CryptoUtil::CryptoUtil(std::wstring mac)
{
CryptoPP::MD5 md5;
byte ivString [] = { "blablabla!@#$&&&&&&&" };
md5.CalculateDigest(m_iv, (byte*) ivString, 20);
char macInChar[12 + 1];
size_t charsConverted = 0;
wcstombs_s(&charsConverted, macInChar, mac.c_str(), mac.length());
md5.CalculateDigest(m_key, (byte*) macInChar, 12);
}
std::wstring CryptoUtil::DecryptStr(std::wstring str)
{
std::string encoded, decoded, recovered;
//change wchar to char
size_t outputSize = str.length() + 1;
char* pBuffer = new char[outputSize];
size_t charsConverted = 0;
wcstombs_s(&charsConverted, pBuffer, outputSize, str.c_str(), str.length());
std::string plain(pBuffer);
delete [] pBuffer;
char * pFormattedStr = new char[outputSize];
int sizeOf = sizeof(pFormattedStr);
sprintf_s(pFormattedStr, outputSize, "%16s", plain.c_str());
encoded = pFormattedStr;
delete [] pFormattedStr;
try
{
StringSource ss(encoded, true,
new CryptoPP::Base64URLDecoder(
new StringSink(decoded)
) // Base64URLDecoder
); // StringSource
CBC_Mode< AES >::Decryption dec;
dec.SetKeyWithIV(m_key, sizeof(m_key), m_iv);
// The StreamTransformationFilter removes
// padding as required.
//StringSource s(cipher, true,
StringSource s(decoded, true,
new StreamTransformationFilter(dec,
new StringSink(recovered)
) // StreamTransformationFilter
); // StringSource
CStringW strTemp = CA2W((char*) recovered.c_str(), CP_UTF8);
strTemp.Trim();
std::wstring strRecovered(strTemp);
return strRecovered;
}
catch (const CryptoPP::Exception& e)
{
throw e;
}
}
我在互联网上做了很多研究,但没有找到解决方案。所以我决定自己做 我创建了一个类来实现这一点!下面的代码自行解释。好看
#pragma once
#include <string>
#include "../../Include/Cryptopp562/aes.h"
using namespace CryptoPP;
//.h
class CryptoUtil
{
public:
CryptoUtil(std::wstring mac);
byte m_key[CryptoPP::AES::DEFAULT_KEYLENGTH];
byte m_iv[CryptoPP::AES::DEFAULT_KEYLENGTH];
char m_macInChar[12];
// decripty string encrypted in AES/CBC/PKCS5Padding mode
std::wstring DecryptStr(std::wstring str);
};
//.cpp
#include "stdafx.h"
#include "CryptoUtil.h"
#include <atlstr.h>
#include "../../Include/Cryptopp562/cryptlib.h"
#include "../../Include/Cryptopp562/filters.h"
#include "../../Include/Cryptopp562/modes.h"
#include "../../Include/Cryptopp562/modes.h"
#include "../../Include/Cryptopp562/aes.h"
#include "../../Include/Cryptopp562/filters.h"
#include "../../Include/Cryptopp562/aes.h"
#include "../../Include/Cryptopp562/base64.h"
#include "../../Include/Cryptopp562/md5.h"
using namespace CryptoPP;
CryptoUtil::CryptoUtil(std::wstring mac)
{
CryptoPP::MD5 md5;
byte ivString [] = { "blablabla!@#$&&&&&&&" };
md5.CalculateDigest(m_iv, (byte*) ivString, 20);
char macInChar[12 + 1];
size_t charsConverted = 0;
wcstombs_s(&charsConverted, macInChar, mac.c_str(), mac.length());
md5.CalculateDigest(m_key, (byte*) macInChar, 12);
}
std::wstring CryptoUtil::DecryptStr(std::wstring str)
{
std::string encoded, decoded, recovered;
//change wchar to char
size_t outputSize = str.length() + 1;
char* pBuffer = new char[outputSize];
size_t charsConverted = 0;
wcstombs_s(&charsConverted, pBuffer, outputSize, str.c_str(), str.length());
std::string plain(pBuffer);
delete [] pBuffer;
char * pFormattedStr = new char[outputSize];
int sizeOf = sizeof(pFormattedStr);
sprintf_s(pFormattedStr, outputSize, "%16s", plain.c_str());
encoded = pFormattedStr;
delete [] pFormattedStr;
try
{
StringSource ss(encoded, true,
new CryptoPP::Base64URLDecoder(
new StringSink(decoded)
) // Base64URLDecoder
); // StringSource
CBC_Mode< AES >::Decryption dec;
dec.SetKeyWithIV(m_key, sizeof(m_key), m_iv);
// The StreamTransformationFilter removes
// padding as required.
//StringSource s(cipher, true,
StringSource s(decoded, true,
new StreamTransformationFilter(dec,
new StringSink(recovered)
) // StreamTransformationFilter
); // StringSource
CStringW strTemp = CA2W((char*) recovered.c_str(), CP_UTF8);
strTemp.Trim();
std::wstring strRecovered(strTemp);
return strRecovered;
}
catch (const CryptoPP::Exception& e)
{
throw e;
}
}
任何行业标准的加密AES等都可以做到这一点。我没有任何代码,但也许它会帮助其他人,如果你解释了你将要使用的一些SSL,Java应有一些库,在C++侧使用RageZ的OpenSSL库。@但在通信过程中,加密是必需的:传输的字符串必须存储在文件的C++客户端上。因此,我将其传输到XML文档中。客户端在需要时对其进行解密。@Robert我用JCE尝试过AES,但没有成功,所以我用JCE尝试了三重DES,但我对输出编码感到困惑。@bluish:我明白了,我想你应该使用其他方法,或者重新加密openssl的输出。任何行业标准的加密AES等都可以做到这一点。我没有任何代码,但也许它会帮助其他人,如果你解释了你将要使用的一些SSL,Java应有一些库,在C++侧使用RageZ的OpenSSL库。@但在通信过程中,加密是必需的:传输的字符串必须存储在文件的C++客户端上。因此,我将其传输到XML文档中。客户端在需要时对其进行解密。@Robert我曾尝试使用JCE对AES进行解密,但没有成功,所以我尝试使用JCE对三重DES进行解密,但我对输出编码感到困惑。@bluish:我明白了,我想你应该使用其他方法,或者重新加密openssl的输出。@ur谢谢!什么是ivBytes?此外,我希望我的加密密钥是字符串,而不是字节数组。还有输出:我需要在xml中发送它,所以我需要一个字符串,我不知道如何发送字节数组。@bluish它是初始化向量。加密和解密时将其设置为相同的16字节。您可以在加密时掷骰子,并使用加密字符串将这16个字节作为明文发送到Java程序。不要使用16个零。要从密码中获取密钥,通常需要使用密钥派生函数
在诸如PBKDF2上,并将其输出用作键。要从字符串中获取字节数组,可以对字符串进行UTF8编码。@sheepsimulator:这是一种密文窃取-一种加密长度不等于AES块大小倍数的数据的方法。再见,谢谢!什么是ivBytes?此外,我希望我的加密密钥是字符串,而不是字节数组。还有输出:我需要在xml中发送它,所以我需要一个字符串,我不知道如何发送字节数组。@bluish它是初始化向量。加密和解密时将其设置为相同的16字节。您可以在加密时掷骰子,并使用加密字符串将这16个字节作为明文发送到Java程序。不要使用16个零。要从密码中获取密钥,通常需要通过密钥派生函数(如PBKDF2)将其作为密钥输出。要从字符串中获取字节数组,可以对字符串进行UTF8编码。@sheepsimulator:这是一种密文窃取-一种加密长度不等于AES块大小倍数的数据的方法。看,我没有投反对票,但我相信这是因为不需要高安全性并不意味着允许非常低的安全性它要么是安全的,要么是模糊的。没有中间立场。你要么努力使你的加密代码防弹,要么你承认失败,并称你的实现为混淆。我非常同意你的第一段,以一种开玩笑的方式。但我认为剩下的部分并不实用。@jweyrich,@thejohndonson,@martona:积分不错。当时我没有想到这个词,但我本应该用模糊这个词。没有中间立场。例如,举例来说,所有的数字版权管理,在哲学基础的意义上,只是真正的热点混淆!即使它可能使用“安全”的东西,比如加密。为什么?如果它是安全的,内容将无法访问!然而,它对这个案例是有用的。至于解决办法是否不切实际,同样取决于具体情况。这就是为什么OP应该确切地告诉我们他想做什么,而不是怎么做的原因。@FastAI,+1,民主的问题是多数不一定总是正确的。如果你成功破解了它,你就称它为模糊处理,如果不是,你就把它作为加密来维护。我没有否决,但我相信这是因为不需要高安全性并不意味着允许非常低的安全性。它要么是安全的,要么是模糊的。没有中间立场。你要么努力使你的加密代码防弹,要么你承认失败,并称你的实现为混淆。我非常同意你的第一段,以一种开玩笑的方式。但我认为剩下的部分并不实用。@jweyrich,@thejohndonson,@martona:积分不错。当时我没有想到这个词,但我本应该用模糊这个词。没有中间立场。例如,举例来说,所有的数字版权管理,在哲学基础的意义上,只是真正的热点混淆!即使它可能使用“安全”的东西,比如加密。为什么?如果它是安全的,内容将无法访问!然而,它对这个案例是有用的。至于解决办法是否不切实际,同样取决于具体情况。这就是为什么OP应该确切地告诉我们他想做什么,而不是怎么做的原因。@FastAI,+1,民主的问题是多数不一定总是正确的。如果破解成功,则称之为混淆,否则将其作为加密进行维护。