2014-04-16 33 views
0

我有一個問題 - 與客戶端,用C#編寫的服務器和C++(Windows MacOs Linux)上的客戶端的加密通信。如何進行rsa加密Ñ++和解密##

我爲Rijndael生成一個密鑰,RSA對它進行加密併發送服務器,服務器使用Rijndael來加密消息。

我的問題是,我不能老是加密RSA,我與公鑰

<RSAKeyValue><Modulus>pmmv...</Modulus><Exponent>AQAB</Exponent></RSAKeyValue> 

我該如何使用C++ XML文件? 可能有一個所有平臺或更好的算法庫,將其包括在草稿中

我在google中找到一種算法,但它需要BigInt的公鑰格式。 如何擺脫XML?

回答

0

演示文稿格式爲RFC 3275,XML-Signature Syntax and Processing

您需要解析RFC 3275 RSAKeyValue,然後將其放入OpenSSL RSA結構中。

它有點痛苦....你確定你想看到它嗎? (XML解析留給讀者一個練習,但它使用上面提供的值)。

#include <stdio.h> 
#include <string.h> 

#include <openssl/bn.h> 
#include <openssl/rsa.h> 
#include <openssl/bio.h> 
#include <openssl/evp.h> 

int main(int argc, char* argv[]) 
{ 
    int ret = -1; 

    char nz[] = "sqprMX0n4y1gmmgpTt6pHb870k5U0MIuXixidD+S8foQf5Bb" 
      "FS44kth2uWDKzXOXqiONxIPHPb+84XdxrRi2O7bvLysztgrF" 
      "eU8oNDMeuIwJOKVQzKoJ1vGqjBKiA9w48oQKxvO+Ck3GmObW" 
      "67LFNcrt50sEco2/OMmrpiH3W8hRx55TcR1flCJduU0/6jA7" 
      "Yct9ZfhOw5wBq6o5IwiT8Mi1R6LVq9sTzSNAWHC/bFcEONkt" 
      "z6NgUKbFKtt+mTfFGToiwPB1L4TecGyTIweH84nl8jVAngcM" 
      "vvFP415Eg1kd9PJbRqrIESM5AU1YcsapWV3bsqEGVS2y+r5N" 
      "4yzXPCYRCRyFWJSnNVlax+gtDFTNz3m9UT8m2E7elGe5hPhR" 
      "6nN3votzBNvTeQ4Lwc5JDIvnWUg7aOdVIXnHQbBqEQke79BX" 
      "xIv8tzVPczGkFqFExkmPPQQv8zJvBKkIYc+BFJtkylBiZfQX" 
      "0590NS3L1y31VSeXn8Ncx2/ceJfUXsMWJ3sQ+dk51MKBJ2LL" 
      "oyJq8IgloBLnXWvlYZ+tkzRVTExFR277V3Jr17DeTOMQGEg5" 
      "HqRkbDDVGPTl2RvC2S2BTe7+r9xNzyAZMieVjZLZgb6icE6u" 
      "SJFcu4qqJ1khQUjW7taymqW8Ao3oEiCUJKvRpZcJPMN+JtMn" 
      "ji+2we17ytk="; 

    char ez[] = "AQAB"; 

    BIO* nn = NULL, *ee = NULL; 
    BIO* b1 = NULL, *b2 = NULL; 
    RSA* rsa = NULL; 

    nn = BIO_new_mem_buf(nz, strlen(nz)); 
    if(!nn) { ret = 1; goto done; } 

    ee = BIO_new_mem_buf(ez, strlen(ez)); 
    if(!ee) { ret = 2; goto done; } 

    b1 = BIO_new(BIO_f_base64()); 
    if(!b1) { ret = 3; goto done; } 

    b2 = BIO_new(BIO_f_base64()); 
    if(!b2) { ret = 4; goto done; } 

    /* If you leave these out even though you */ 
    /* are reading, then BIO_read will return 0 */ 
    /* and BIO_should_retry will return false */ 
    BIO_set_flags(b1, BIO_FLAGS_BASE64_NO_NL); 
    BIO_set_flags(b2, BIO_FLAGS_BASE64_NO_NL); 

    nn = BIO_push(b1, nn); 
    if(!nn) { ret = 5; goto done; } 

    ee = BIO_push(b2, ee); 
    if(!ee) { ret = 6; goto done; } 

    rsa = RSA_new(); 
    if(rsa == NULL) { ret = 7; goto done; } 

    unsigned char buff[4096]; 
    const int bsize = sizeof(buff); 
    int rr = 0, rd = 0; 

    /* See http://marc.info/?l=openssl-users&m=123171064303018&w=2 */ 
    /* for this contorted goodness */ 
    rd = 0; 
    do { 
     rr = BIO_read(nn, buff + rd, bsize - rd); 
     if(rr < 0) { ret = 8; goto done; } /* failed */ 

     rd += rr; 
    } while (rr > 0 || BIO_should_retry(nn)); 

    if(rd == 0) { ret = 9; goto done; } 

    rsa->n = BN_bin2bn(buff, rd, NULL); 
    if(rsa->n == NULL) { ret = 10; goto done; } 

    rd = 0; 
    do { 
     rr = BIO_read(ee, buff + rd, bsize - rd); 
     if(rr < 0) { ret = 11; goto done; } /* failed */ 

     rd += rr; 
    } while (rr > 0 || BIO_should_retry(ee)); 

    if(rd == 0) { ret = 12; goto done; } 

    rsa->e = BN_bin2bn(buff, rd, NULL); 
    if(rsa->e == NULL) { ret = 13; goto done; } 

    /***** Paydirt *****/ 

    RSA_print_fp(stdout, rsa, 0); 

    ret = 0; 

done: 

    if(ret != 0) 
     fprintf(stderr, "Failed to parse and validate RSA key\n"); 

    if(rsa) 
     RSA_free(rsa), rsa = NULL; 

    if(nn) 
     BIO_free_all(nn), nn = NULL; 

    if(ee) 
     BIO_free_all(ee), ee = NULL; 

    return ret; 
} 
+0

非常好這個工作,但服務器不理解我,說不能解密消息 – user2618420

+0

檢查客戶端能夠解密加密數據而不服務器。 另請檢查您是否在客戶端和服務器端具有相同的XML數據。 將數據保存到服務器和客戶端上的文件,並使用fc比較這些文件。 – tas

+0

可以解密 並且服務器顯示錯誤「壞數據」 – user2618420

0

通過解析XML,base 64解碼文本中的文本,並使用生成的字節數組創建一個無符號大整數,一個用於模數,另一個用於公共指數(儘管後者可能始終爲0x10001或65537 - Fermat F4的第四個數字 - 就像現在的密鑰對生成器一樣)。

如果您只需要執行此操作,則還可以base 64解碼字符串並手動將結果複製到C++代碼中。