我有一个用C++ for Windows编写的现有应用程序.此应用程序使用Win32 CryptoAPI生成用于加密/解密数据的TripleDES会话密钥.我们使用一个技巧的指数将会话密钥导出为blob,这允许blob以解密格式存储在某处.
问题是我们如何在.NET应用程序(C#)中使用它.该框架封装/包装了CryptoAPI正在做的大部分内容.部分问题是CryptAPI声明Microsoft增强加密提供程序的TripleDES算法是168位(56位的3个密钥).但是,.NET框架声明它们的密钥是192位(64位的3个密钥).显然,.NET框架中的3个额外字节用于奇偶校验?
无论如何,我们需要从blob中读取关键部分,并以某种方式能够在我们的.NET应用程序中使用它.目前,我们在尝试在.NET中使用密钥时没有得到预期的结果.解密失败了.任何帮助将不胜感激.
我一直在努力解决这个问题,并提出了一个我将及时发布的解决方案.但是,仍然会感谢来自其他人的任何反馈.
我需要使用512位RSA公钥加密一小块数据(16字节) - 对于我所知的大多数加密库来说,这是一项非常简单的任务,除了MS CSP API之外,它似乎也是如此.CryptEncrypt函数的文档说明了这一点
Microsoft增强加密提供程序支持使用RSA公钥进行直接加密,并使用RSA私钥进行解密.加密使用PKCS#1填充.
但它对我没用.好吧,我的代码工作并生成具有正确大小的加密数据块,但是openssl无法对其进行decypher.它看起来很像CryptEncrypt仍然使用对称密码.
不幸的是,我发现的所有例子都是指带有对称密码的组合密码术,所以我手上没有一个工作示例,这肯定会让事情变得更容易.
可以请任何人指出我这样的例子或让我知道是否有一些我错过的明显陷阱?
谢谢.
我需要比较两个字符串的哈希值。我使用字符串“template”进行测试。但我得到了这个字符串的不同哈希值,所以它总是不一样。我使用 CryptoApi 和 MD4
int _tmain(int argc, _TCHAR* argv[])
{
std::hash_map<int,int> table;
HCRYPTPROV hProv1,hProv2;
BYTE *pbBuffer1=(BYTE*)"template";//data to hash
DWORD dwBufferLen1=strlen((char*)pbBuffer1)+1;
HCRYPTHASH hHash1,hHash2;
//first hash
CryptAcquireContext(&hProv1,NULL,NULL,PROV_RSA_AES,0);
CryptCreateHash(hProv1,CALG_MD4,0,0,&hHash1);
CryptHashData(hHash1,pbBuffer1,dwBufferLen1,0);
/*---------*/
BYTE *pbBuffer2=(BYTE*)"template";//data to hash
DWORD dwBufferLen2=strlen((char*)pbBuffer2)+1;
//second hash
CryptAcquireContext(&hProv2,NULL,NULL,PROV_RSA_AES,0);
CryptCreateHash(hProv2,CALG_MD4,0,0,&hHash2);
CryptHashData(hHash2,pbBuffer2,dwBufferLen2,0);
if (hHash1==hHash2)
printf("The Same\n");
else printf("Not same\n");
/*---------*/
std::cout<<hHash1<<std::endl;
std::cout<<hHash2<<std::endl;
if (hProv1)
CryptReleaseContext(hProv1,0);
if (hProv2)
CryptReleaseContext(hProv2,0);
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
例如hHash1中的哈希值
691136
Run Code Online (Sandbox Code Playgroud)
hHash2 中的哈希值
691216
Run Code Online (Sandbox Code Playgroud) 如何使用Microsoft Crypto API 中的“证书”加密数据?
我知道如何使用 AES 加密通过 Microsoft Crypto API 加密数据:
keyBlob.hdr.bType := PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion := CUR_BLOB_VERSION;
keyBlob.hdr.reserved := 0;
keyBlob.hdr.aiKeyAlg := CALG_AES_128;
keyBlob.cbKeySize := 16;
Move(data[0], keyBlob.key[0], 16);
/*
Set ProviderName to either
providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider"
providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)" //Windows XP and earlier
*/
MS_ENH_RSA_AES_PROV_W: WideString = 'Microsoft Enhanced RSA and AES Cryptographic Provider';
providerName := MS_ENH_RSA_AES_PROV_W;
CryptAcquireContextW(provider, nil, PWideChar(providerName), PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
CryptImportKey(provider, PByte(@keyBlob), …
Run Code Online (Sandbox Code Playgroud) 我正在将一个旧的VB6应用程序移植到.NET,我从昨天下午开始遇到一些问题,我遇到了一些CryptoAPI调用.
特别是我无法检索已定义的密钥容器.我用的是这个CryptAcquireContext()
功能.我在创建容器时使用了一些测试代码.然后,如果我去,C:\Users...\Roaming\Microsoft\Crypto\RSA\Machine Keys\
我可以看到用我定义的容器名称创建的文件,所以我假设它已成功创建.
尝试创建相同容器的后续调用验证了该假设,因为我得到了已定义键集的win32错误.
无论如何,在我的下一个代码调用中,我尝试检索已经创建的容器,我得到了Windows错误,没有定义键集.
错误:-2146893799(80090019)未定义键集.
有任何想法吗?
这是一个代码示例:
public const uint PROV_RSA_FULL = 1;
public const uint CRYPT_NEWKEYSET = 0x00000008;
public const uint CRYPT_MACHINE_KEYSET = 0x00000020;
const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);
public static void CreateContainer()
{
IntPtr hCryptProv;
int error;
if (!CryptAcquireContext(out hCryptProv, "new", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
error = Marshal.GetLastWin32Error(); …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用AES算法编写一个简单的程序来加密和解密文件.我没有加密问题,但解密..
public static void main(String[] args) throws NoSuchAlgorithmException, FileNotFoundException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// ????????????? ????????? ??????
KeyGenerator keyGenS = KeyGenerator.getInstance("AES");
keyGenS.init(128);
SecretKey sKey1 = keyGenS.generateKey();
SecretKey sKey2 = keyGenS.generateKey();
// ??????? ????????? ?????? ? ?????? ? ?????? ? ????
String key1 = SecretKeyToString(sKey1);
String key2 = SecretKeyToString(sKey2);
spreader.write(fileName1, key1);
spreader.write(fileName2, key2);
spreader.write(fileNameS1, key1);
spreader.write(fileNameS2, key2);
// ?????? ????????? ?????? ?? ????? ? ??????? ??????? ? ??? SecretKey
key1 = spreader.read(fileName1);
System.out.println("????????? ???? 1?? ????????????: " +key1);
SecretKey seansKey1=getKeyInstance(key1); …
Run Code Online (Sandbox Code Playgroud) 如标题所示,我正在寻找cryptopp 库中此声明之间的差异:
CBC_Mode<AES>::Decryption
cbcDecryption.SetKeyWithIV(key, AES::DEFAULT_KEYLENGTH, iv);
Run Code Online (Sandbox Code Playgroud)
和这个:
AES::Decryption aesDecryption(key, AES::DEFAULT_KEYLENGTH);
CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );
Run Code Online (Sandbox Code Playgroud)
此外,我不明白为什么这样:
AES::Decryption aesDecryption(key, AES::DEFAULT_KEYLENGTH);
CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );
StreamTransformationFilter stfDecryptor(
cbcDecryption,
new StringSink( recoveredtext )
);
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ), ciphertext.size() );
stfDecryptor.MessageEnd();
Run Code Online (Sandbox Code Playgroud)
使用模板模式时一切正常我在运行时遇到此错误:
AES128CBC: /usr/local/include/cryptopp/misc.h:304: void CryptoPP::memcpy_s(void*, size_t, const void*, size_t): Assertion `dest != __null' failed.
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
不应该是一样的吗?
我看过这个,但我不太明白其中的区别,在网上搜索我找不到问题的答案。
在 Windows 机器上,我想创建一个 C++ 代码,将 Windows 根证书导出到.pem \ .crt
文件(就像 certmgr.msc 工具允许我手动执行一样)。目前正在挖掘 windows 的 cryptoAPI 文档,但没有找到任何东西。
编辑:使用下面的解决方案后,PEM 证书以以下格式创建(行之间不需要换行符,末尾有一个额外的字符):-----BEGIN CERTIFICATE-----
MIICvDCCAiUCEEoZ0jiMglkcpV1zXxVd3KMwDQYJKoZIhvcNAQEEBQAwgZ4xHzAd
BgNVBAoTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxFzAVBgNVBAsTDlZlcmlTaWdu
....
Rj1QNAufcFb2jip/F87lY795aQdzLrCVKIr17aqp0l3NCsoQCY/Os68olsR5KYSS
3P+6Z0JIppAQ5L9h+JxT5ZPRcz/4/Z1PhKxV0f0RY2M=
-----结束证书-----
我不相信它会被 openSSL 接受,这是什么原因?
我正在尝试使用IXmlEncryptor实现静态加密。特别是使用 CertificateEncryptor。(这是 IXmlRepository 系统的一部分,用于在 ASP.NET Core 中共享用于解密 cookie 和一般密钥管理的密钥。)
此文档页面讨论了为此目的使用 X.509 证书。
它表示“仅支持带有CAPI 私钥的证书”。
谷歌搜索显示 CAPI 意味着 Microsoft CryptAPI。但我找不到更多关于它的信息,我能找到的似乎与 C++ 相关。
当我问他什么是“CAPI 私钥”时,我的“证书人员”基本上告诉了我这一点:
Microsoft 生成的转换为 x509 的 PFX 文件有密码。那将是我唯一能想到的。
那是同一件事吗?
如果没有,如何创建带有 CAPI 私钥的 X.509 证书?
注意:X.509 证书是文档页面上列出的可在Linux 机器(容器)上运行的唯一选项。这就是为什么我不考虑任何其他(可能更简单)的选择。
encryption certificate cryptoapi x509certificate asp.net-core
我希望能够使用Microsoft CryptoAPI验证OpenSSL生成的DSA签名.
考虑您有以下输入:
签名已从Base64转换为48个字节的系列.
cryptoapi ×10
c++ ×3
certificate ×3
cryptography ×3
encryption ×3
.net ×2
asp.net-core ×1
c# ×1
crypto++ ×1
java ×1
openssl ×1
pem ×1
rsa ×1