Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#和C+之间的Diffie-Hellman密钥交换+;在窗户上_C#_C++_Windows_Diffie Hellman_Public Key Exchange - Fatal编程技术网

C#和C+之间的Diffie-Hellman密钥交换+;在窗户上

C#和C+之间的Diffie-Hellman密钥交换+;在窗户上,c#,c++,windows,diffie-hellman,public-key-exchange,C#,C++,Windows,Diffie Hellman,Public Key Exchange,我想使用Diffie-Hellman算法在C++服务器和运行在Windows上的C#客户端之间安全地交换密钥。我尝试在C中使用ecdiffiehellmancing生成公钥,如下所示: ECDiffieHellmanCng diffieHellman = new ECDiffieHellmanCng { KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash, HashAlgorithm = CngAlg

我想使用
Diffie-Hellman
算法在
C++
服务器和运行在
Windows
上的
C#
客户端之间安全地交换密钥。我尝试在
C
中使用
ecdiffiehellmancing
生成公钥,如下所示:

ECDiffieHellmanCng diffieHellman = new ECDiffieHellmanCng
{
    KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash,
    HashAlgorithm = CngAlgorithm.Sha256
};

byte[] publicKey = diffieHellman.PublicKey.ToByteArray(); // 140 bytes
此外,我使用以下代码导出AES密钥:

var cngKey = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
var aesKey = diffieHellman.DeriveKeyMaterial(cngKey); // 32 bytes
这在
C#
上下文中运行良好,但是我需要它与
C++
交互

是否有任何
C++
库或代码与
ecdiffiehellmancing
兼容?我研究了
Crypto++
,它似乎与我的
C#
密钥交换方法不兼容


不管怎样,执行密钥交换的任何其他建议或代码示例都是受欢迎的。

因为我只是想要一个加密连接,所以使用是最好的选择。

也许这会对您有所帮助

#pragma warning(disable : 4996)

#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include "openssl/dh.h"
#include "openssl/bn.h"
#include "openssl/pem.h";
using namespace std;

DH *dhp = NULL;

static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

static inline bool is_base64(unsigned char c) {
    return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
    std::string ret;
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];

    while (in_len--) {
        char_array_3[i++] = *(bytes_to_encode++);
        if (i == 3) {
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;

            for (i = 0; (i < 4); i++)
                ret += base64_chars[char_array_4[i]];
            i = 0;
        }
    }

    if (i)
    {
        for (j = i; j < 3; j++)
            char_array_3[j] = '\0';

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; (j < i + 1); j++)
            ret += base64_chars[char_array_4[j]];

        while ((i++ < 3))
            ret += '=';

    }

    return ret;

}
std::string base64_decode(std::string const& encoded_string) {
    int in_len = encoded_string.size();
    int i = 0;
    int j = 0;
    int in_ = 0;
    unsigned char char_array_4[4], char_array_3[3];
    std::string ret;

    while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
        char_array_4[i++] = encoded_string[in_]; in_++;
        if (i == 4) {
            for (i = 0; i < 4; i++)
                char_array_4[i] = base64_chars.find(char_array_4[i]);

            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

            for (i = 0; (i < 3); i++)
                ret += char_array_3[i];
            i = 0;
        }
    }

    if (i) {
        for (j = i; j < 4; j++)
            char_array_4[j] = 0;

        for (j = 0; j < 4; j++)
            char_array_4[j] = base64_chars.find(char_array_4[j]);

        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
        char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

        for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
    }

    return ret;
}

int main(int argc, char *argv[])
{
    BIGNUM* priv_key = NULL;
    BIGNUM* apub_key = NULL;
    BIGNUM* p = NULL;
    BIGNUM* g = NULL;
    std::string userPubKey;
    std::string prime;
    std::string generator;

    if (argc < 6) {
        printf("%s", "Missing parameters: -p, -key -g");
        return -1;
    }

    //Process parameters
    int count;
    for (count = 1; count < argc; count+=2)
    {
        std::string param = (string)argv[count];

        if (strcmpi(param.c_str(), "-p") == 0) {
            prime = (string)argv[count+1];
        }
        else if (strcmpi(param.c_str(), "-key") == 0) {
            userPubKey = (string)argv[count + 1];
        }
        else if (strcmpi(param.c_str(), "-g") == 0) {
            generator = (string)argv[count+1];
        }
    }

    //Set public key of remote User
    BN_hex2bn(&apub_key, userPubKey.c_str());

    DH *dhp = DH_new();
    if (dhp == NULL) {
        return -1;
    }
    
    //Set Prime and Generator
    BN_hex2bn(&p, prime.c_str());
    BN_dec2bn(&g, generator.c_str());
    DH_set0_pqg(dhp, p, NULL, g);

    if (DH_generate_key(dhp) != 1) {
        printf("%s", "Error generating keys.");
        return -1;
    }

    //Print Public Key as Hex
    const BIGNUM* exportPublic = DH_get0_pub_key(dhp);
    printf("Public Key: %s\r\n", BN_bn2hex(exportPublic));

    //Calculate secret
    char buf[256] = { 0 };
    unsigned char* abuf = NULL;
    int alen = DH_size(dhp);
    abuf = (unsigned char*)OPENSSL_malloc(alen);

    int aout = DH_compute_key(abuf, apub_key, dhp);
    printf("\r\nThe shared secret is:\r\n");
    std::string encoded = base64_encode(abuf, aout);
    printf("%s\r\n", encoded.c_str());

    DH_free(dhp);
    p = NULL;
    g = NULL;
    abuf = NULL;
}
#杂注警告(禁用:4996)
#包括
#包括
#包括
#包括
#包括“openssl/dh.h”
#包括“openssl/bn.h”
#包括“openssl/pem.h”;
使用名称空间std;
DH*dhp=NULL;
静态常量std::字符串base64_字符=
“ABCDEFGHIJKLMNOPQRSTUVWXYZ”
“abcdefghijklmnopqrstuvwxyz”
"0123456789+/";
静态内联bool是_base64(无符号字符c){
返回(isalnum(c)| |(c='+')| | |(c=='/'));
}
std::string base64_encode(无符号字符常量*bytes_to_encode,无符号整数in_len){
std::字符串ret;
int i=0;
int j=0;
无符号字符数组3[3];
无符号字符数组4[4];
而(在_len--){
字符数组3[i++]=*(字节到编码++);
如果(i==3){
char_数组_4[0]=(char_数组_3[0]&0xfc)>>2;
char_数组_4[1]=((char_数组_3[0]&0x03)>4);
char_数组_4[2]=((char_数组_3[1]&0x0f)>6);
char_数组_4[3]=char_数组_3[2]&0x3f;
对于(i=0;(i<4);i++)
ret+=base64_字符[char_数组_4[i];
i=0;
}
}
如果(i)
{
对于(j=i;j<3;j++)
字符数组_3[j]='\0';
char_数组_4[0]=(char_数组_3[0]&0xfc)>>2;
char_数组_4[1]=((char_数组_3[0]&0x03)>4);
char_数组_4[2]=((char_数组_3[1]&0x0f)>6);
char_数组_4[3]=char_数组_3[2]&0x3f;
对于(j=0;(j4);
char_数组_3[1]=((char_数组_4[1]&0xf)>2);
char_数组_3[2]=((char_数组_4[2]&0x3)4);
char_数组_3[1]=((char_数组_4[1]&0xf)>2);

char_array_3[2]=((char_array_4[2]&0x3)1)您真的需要为每个客户端动态生成服务器密钥吗?我觉得这不太合适。客户端应该以某种方式信任服务器在连接时的公钥(硬编码发布密钥或使用第三方通道进行检查),对吗?2)你就不能只使用TLS,避免干预低级的东西吗?@Maxisagaydachny:我真的不需要,但我认为用
AES
实现
Diffie Hellman
就足够容易了,显然不是。也许为服务器和客户端设置
TLS
更可行、更标准。我也会尝试一下但由于不同的技术必须相互作用,它可能是另一个蠕虫罐头。