int COsslKey::setPublicKeyRaw( sqbind::CSqBinary *pBin ) {_STT(); Destroy(); if ( !pBin || !pBin->getUsed() ) return 0; m_pkey = EVP_PKEY_new(); if ( !m_pkey ) { oexERROR( 0, oexT( "EVP_PKEY_new() failed" ) ); Destroy(); return 0; } // end if const unsigned char *p = (const unsigned char*)pBin->Ptr(); RSA *rsa = d2i_RSAPublicKey( oexNULL, &p, pBin->getUsed() ); if ( !rsa ) { oexERROR( 0, oexT( "d2i_RSAPrivateKey() failed" ) ); Destroy(); return 0; } // end if // Assign key if ( !EVP_PKEY_assign_RSA( m_pkey, rsa ) ) { oexERROR( 0, oexT( "EVP_PKEY_assign_RSA() failed" ) ); Destroy(); return 0; } // end if rsa = oexNULL; return 1; }
bool UpdateManager::verifyVersionData(const string& data, const ByteVector& signature) { int res = -1; // Make SHA hash SHA_CTX sha_ctx = { 0 }; uint8_t digest[SHA_DIGEST_LENGTH]; res = SHA1_Init(&sha_ctx); if(res != 1) return false; res = SHA1_Update(&sha_ctx, data.c_str(), data.size()); if(res != 1) return false; res = SHA1_Final(digest, &sha_ctx); if(res != 1) return false; // Extract Key const uint8_t* key = UpdateManager::publicKey; RSA* rsa = d2i_RSAPublicKey(NULL, &key, sizeof(UpdateManager::publicKey)); if(rsa) { res = RSA_verify(NID_sha1, digest, sizeof(digest), &signature[0], signature.size(), rsa); RSA_free(rsa); rsa = NULL; } else return false; return (res == 1); }
main(){ unsigned char *pem_key_str = "MIGJAoGBAKz8scCXFg2O2r2sMsic40hSgHw1q52LUAvEHDH4S5pgflNjs8NfJKOjZmnkTpxI+eLmGKqPPWg7SF7YbUMmmTXvhuTWQF9OcXhIxzIUVFwQKZEWSgZyoaqwcy3XF6sIf7oFDRWfkIY5RCp03GdM0IjGK3lDIdfh0p6wSjTdfvvhAgMBAAEwggJcAgEAAoGBAKz8scCXFg2O2r2sMsic40hSgHw1q52LUAvEHDH4S5pgflNjs8NfJKOjZmnkTpxI+eLmGKqPPWg7SF7YbUMmmTXvhuTWQF9OcXhIxzIUVFwQKZEWSgZyoaqwcy3XF6sIf7oFDRWfkIY5RCp03GdM0IjGK3lDIdfh0p6wSjTdfvvhAgMBAAECgYBo1D1Xq3dWwgI2vPqNbd2h/zUTkGauczUP3EkF0yTlqaIEIMBYHfkTHTs74nns5aBg6vV5rpIU7w/9QgR8lBB1it3g6QU8RWdLG1cpckEL8LLPPWPIUOTSaId2BAeIU3Q0NOBc0sWO1pUTvYBGykQW9LYsP3254yIbc+5aQhwjAQJBANUh5TA45sMvpK+ZoRd3rWTQMU3Ted2/MCsGknPSPCk9ZxHTknU+q5O8L2kmWuc0b/IrVp4Zi9AUDx9AplRUvjECQQDPx7t6Iaim+jjO5y9FcKQPnFW4PRD2s2OffGisrIVAoLoQqNeHW5itltEs/CIT2AyTYRhg4uBIC37gt3kelDyxAkBhNv24Oiwf2apvok6VSrRfaIskqZJLr/pDldLVW46vbN+HhQ6nxfczAsJJXwJVtVheiKAQqyxXs96V7cIwcxrxAkEAihggRRK7yYaCXRkPtOIhV/K6kgGcFaqyapw/4Yuj4IkyQMJGxMKe3bhf+7rzVyb/bLBaiIIhOCDTybyHNkilcQJAHNSMtPgDVvYbzImMaNcpGHKJdkPoChO7W7EpRuCMlT7OMIc8cQIOiTBrHRDzF72NT0p+QfAXUAZxat7s1oqSDw=="; RSA *pub_rsa,*priv_rsa; unsigned char de_buf[2048],*p,*start; int de_len; p=de_buf; base64_decode(pem_key_str,strlen(pem_key_str),de_buf,&de_len); p = (unsigned char*)malloc(de_len); memcpy(p,de_buf,de_len); start = p; pub_rsa=d2i_RSAPublicKey(NULL,(const unsigned char**)&p,(long)de_len); de_len-=(p-start); priv_rsa=d2i_RSAPrivateKey(NULL,(const unsigned char**)&p,(long)de_len); if ((pub_rsa == NULL) || (priv_rsa == NULL)) ERR_print_errors_fp(stderr); RSA_print_fp(stdout,pub_rsa,11); RSA_print_fp(stdout,priv_rsa,11); RSA_free(pub_rsa); RSA_free(priv_rsa); }
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; if ((a == NULL) || (*a == NULL)) { if ((ret = EVP_PKEY_new()) == NULL) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); return (NULL); } } else ret = *a; if (!EVP_PKEY_set_type(ret, type)) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); goto err; } switch (EVP_PKEY_id(ret)) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); goto err; } break; #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: /* TMP UGLY CAST */ if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); goto err; } break; #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); goto err; } break; #endif default: ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; /* break; */ } if (a != NULL) (*a) = ret; return (ret); err: if (a == NULL || *a != ret) EVP_PKEY_free(ret); return (NULL); }
extern "C" RSA* DecodeRsaPublicKey(const unsigned char* buf, int32_t len) { if (!buf || !len) { return nullptr; } return d2i_RSAPublicKey(nullptr, &buf, len); }
extern "C" RSA* CryptoNative_DecodeRsaPublicKey(const uint8_t* buf, int32_t len) { if (!buf || !len) { return nullptr; } return d2i_RSAPublicKey(nullptr, &buf, len); }
/* Creates an X509 certificate request (1st stage). */ EXPORT int MakeCertificateRequest(unsigned char *reqbuf, int *reqlen, char *x500dn, unsigned char *rsabuf, int rsalen) { EVP_PKEY *pkey = NULL; RSA *rsa = NULL; unsigned char *p = NULL; int ret = OPENSSLCA_NO_ERR; if (reqbuf == NULL || reqlen == NULL || x500dn == NULL || rsabuf == NULL || rsalen == 0) return OPENSSLCA_ERR_ARGS; /* Decode RSA public key from DER format */ if ((rsa = RSA_new()) == NULL) { ret = OPENSSLCA_ERR_RSA_NEW; goto err; } p = rsabuf; if (d2i_RSAPublicKey(&rsa, &p, rsalen) == NULL) { ret = OPENSSLCA_ERR_RSA_DECODE; goto err; } /* Add RSA to EVP_PKEY */ if ((pkey = EVP_PKEY_new()) == NULL) { ret = OPENSSLCA_ERR_KEY_NEW; goto err; } if (!EVP_PKEY_set1_RSA(pkey, rsa)) { ret = OPENSSLCA_ERR_KEY_ASSIGN; goto err; } #ifdef _DEBUG { FILE *fp = fopen(DBG_PATH("rsa.bin"), "wb"); if (fp != NULL) { i2d_RSAPublicKey_fp(fp, rsa); fclose(fp); } } #endif ret = MakeCertificateRequest2(reqbuf, reqlen, x500dn, pkey); err: print_err("MakeCertificateRequest()", ret); if (rsa) RSA_free(rsa); if (pkey) EVP_PKEY_free(pkey); return ret; }
static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p; int pklen; RSA *rsa = NULL; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) return 0; if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) { RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); return 0; } EVP_PKEY_assign_RSA(pkey, rsa); return 1; }
static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const uint8_t *p; int pklen; RSA *rsa; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) { return 0; } rsa = d2i_RSAPublicKey(NULL, &p, pklen); if (rsa == NULL) { OPENSSL_PUT_ERROR(EVP, rsa_pub_decode, ERR_R_RSA_LIB); return 0; } EVP_PKEY_assign_RSA(pkey, rsa); return 1; }
RSAKey RSAKey::createFromPublicCompound(const std::vector<unsigned char>& data) { const unsigned char* buf = reinterpret_cast<const unsigned char*>(&data[0]); RSA* prsa = NULL; if (!d2i_RSAPublicKey(&prsa, &buf, static_cast<long>(data.size()))) { THROW_EXCEPTION_WITH_LOG(OpenSSLException, "Unable to read public key compound from the specified buffer."); } else { std::shared_ptr<RSA> sprsa(prsa, RSA_free); return RSAKey(sprsa, false); } }
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; if ((a == NULL) || (*a == NULL)) { if ((ret=EVP_PKEY_new()) == NULL) { ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB); return(NULL); } } else ret= *a; ret->save_type=type; ret->type=EVP_PKEY_type(type); switch (ret->type) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: if ((ret->pkey.rsa=d2i_RSAPublicKey(NULL, (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */ { ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB); goto err; } break; #endif default: ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; /* break; */ } if (a != NULL) (*a)=ret; return(ret); err: if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret); return(NULL); }
static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p; int pklen; X509_ALGOR *alg; RSA *rsa = NULL; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) return 0; if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) { RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); return 0; } if (!rsa_param_decode(rsa, alg)) { RSA_free(rsa); return 0; } EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); return 1; }
wi_rsa_t * wi_rsa_init_with_public_key(wi_rsa_t *rsa, wi_data_t *data) { const unsigned char *buffer; long length; buffer = wi_data_bytes(data); length = wi_data_length(data); rsa->rsa = d2i_RSAPublicKey(NULL, (const unsigned char **) &buffer, length); if(!rsa->rsa) { wi_error_set_openssl_error(); wi_release(rsa); return NULL; } rsa->public_key = wi_retain(data); return rsa; }
/* * get_rsa_pub * * Converts a dump of a rsa pub key to a RSA structure, which is returned. * Remeber to RSA_free() the returned key. */ RSA *get_rsa_pub(const u_char **pub_key, long length) { return d2i_RSAPublicKey(NULL, pub_key, length); }
int main(int argc, char* argv[]) { RSA* param = NULL; FILE* pub_key; FILE* input; FILE* signature; long size_klucz, size_podpis; unsigned char data[1024]; unsigned char md5_sum[MD5_DIGEST_LENGTH]; int bytes; if(argc != 3) { printf("Niewlasciwa liczba argumentow. Skladnia: %s <plik_z_podpisem> <plik_podpisany>\n"); return 1; } signature = fopen(argv[1], "rb"); input = fopen(argv[2], "rb"); pub_key = fopen("pub.key", "rb"); if(signature == NULL || input == NULL || pub_key == NULL) { printf("Blad podczas otwierania plikow\n"); return 1; } MD5_CTX ctx; if(!MD5_Init(&ctx)) { printf("Blad funkcji MD5_Init\n"); return 1; } while(bytes = fread(data, sizeof(unsigned char), 1024, input)) { if(!MD5_Update(&ctx, data, bytes)) { printf("Blad funkcji MD5_Update\n"); return 1; } } if(!MD5_Final(md5_sum, &ctx)) { printf("Blad funkcji MD5_Update\n"); return 1; } fseek(pub_key, 0, SEEK_END); size_klucz=ftell(pub_key); rewind(pub_key); fseek(signature, 0, SEEK_END); size_podpis=ftell(signature); rewind(signature); unsigned char* buf_klucz = (unsigned char*) malloc(size_klucz*sizeof(unsigned char)); fread(buf_klucz, sizeof(unsigned char*), size_klucz, pub_key); unsigned char* buf_podpis = (unsigned char*) malloc(size_podpis*sizeof(unsigned char)); fread(buf_podpis, sizeof(unsigned char*), size_podpis, signature); const unsigned char* p = buf_klucz; d2i_RSAPublicKey(¶m, &p, size_klucz); if(param == NULL) { printf("Blad podczas tworzenia struktury dsa\n"); return 1; } int w; w=RSA_verify(NID_md5, md5_sum, sizeof(md5_sum), buf_podpis, size_podpis, param); if(w==1) printf("Podpis jest prawidlowy\n"); else printf("Podpis jest nieprawidlowy.\n"); free(buf_klucz); free(buf_podpis); fclose(signature); fclose(input); fclose(pub_key); return 0; }
int main( int argc, char* argv[] ) { if( argv[ 1 ] == std::string( "--sign" ) ) { boost::asio::io_service ioService; const auto host = "127.0.0.1"; const auto port = argv[ 2 ]; Client< ReaderSign, WriterSign >( ioService, host, port, argc, argv ); } else if( argv[ 1 ] == std::string( "--key" ) ) { boost::asio::io_service ioService; const auto host = "127.0.0.1"; const auto port = argv[ 2 ]; Client< ReaderKey, WriterKey >( ioService, host, port ); } else if( argv[ 1 ] == std::string( "--verify" ) ) { char sha1[ 1024 ]; { SHA_CTX ctx; SHA1_Init( & ctx ); char buffer[ 4 * 1024 ]; std::ifstream fileIn( argv[ 2 ], std::ios_base::in | std::ios_base::binary ); while( fileIn.read( & buffer[ 0 ], sizeof( buffer ) ) ) { SHA1_Update( & ctx, & buffer[ 0 ], sizeof( buffer ) ); } SHA1_Update( & ctx, & buffer[ 0 ], fileIn.gcount() ); SHA1_Final( (unsigned char*)( & sha1[ 0 ] ), & ctx ); } RSA * rsa = nullptr; { std::ifstream keyFile( argv[ 3 ], std::ios_base::in | std::ios_base::binary ); char key[ 1024 ]; keyFile.read( key, 1024 ); unsigned keySize = keyFile.gcount(); unsigned char const * buffer = (unsigned char const*)( & key[ 0 ] ); rsa = d2i_RSAPublicKey( nullptr, & buffer, keySize ); } std::ifstream signatureFile( argv[ 4 ], std::ios_base::binary ); char signature[ 1024 ]; signatureFile.read( signature, 1024 ); unsigned signatureSize = signatureFile.gcount(); const auto verifyResult = RSA_verify( NID_sha1, (unsigned char const*)( & sha1 ), SHA_DIGEST_LENGTH, (unsigned char const*) signature, signatureSize, rsa ); if( verifyResult == 1 ) { std::cout << "OK" << std::endl; } else { std::cout << "Failed" << std::endl; } return ! verifyResult; } else { std::cout << "Usage: " << argv[ 0 ] << '\n' << " --sign <port> <filename>\n" << " --key <port>\n" << " --verify <messagefile> <keyfile> <signaturefile>\n"; return 1; } return 0; }
/* * Decode a string to a key. Return 0 on success. */ int kn_decode_key(struct keynote_deckey *dc, char *key, int keytype) { void *kk = NULL; X509 *px509Cert; EVP_PKEY *pPublicKey; unsigned char *ptr = NULL, *decoded = NULL; int encoding, internalencoding; long len = 0; keynote_errno = 0; if (keytype == KEYNOTE_PRIVATE_KEY) dc->dec_algorithm = keynote_get_private_key_algorithm(key, &encoding, &internalencoding); else dc->dec_algorithm = keynote_get_key_algorithm(key, &encoding, &internalencoding); if (dc->dec_algorithm == KEYNOTE_ALGORITHM_NONE) { if ((dc->dec_key = strdup(key)) == NULL) { keynote_errno = ERROR_MEMORY; return -1; } return 0; } key = strchr(key, ':'); /* Move forward, to the Encoding. We're guaranteed * to have a ':' character, since this is a key */ key++; /* Remove ASCII encoding */ switch (encoding) { case ENCODING_NONE: break; case ENCODING_HEX: len = strlen(key) / 2; if (kn_decode_hex(key, (char **) &decoded) != 0) return -1; ptr = decoded; break; case ENCODING_BASE64: len = strlen(key); if (len % 4) /* Base64 encoding must be a multiple of 4 */ { keynote_errno = ERROR_SYNTAX; return -1; } len = 3 * (len / 4); decoded = calloc(len, sizeof(unsigned char)); ptr = decoded; if (decoded == NULL) { keynote_errno = ERROR_MEMORY; return -1; } if ((len = kn_decode_base64(key, decoded, len)) == -1) return -1; break; case ENCODING_NATIVE: decoded = strdup(key); if (decoded == NULL) { keynote_errno = ERROR_MEMORY; return -1; } len = strlen(key); ptr = decoded; break; default: keynote_errno = ERROR_SYNTAX; return -1; } /* DSA-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_DSA) && (internalencoding == INTERNAL_ENC_ASN1)) { dc->dec_key = DSA_new(); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_DSAPrivateKey((DSA **) &kk,(const unsigned char **) &decoded, len) == NULL) { free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } else { if (d2i_DSAPublicKey((DSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } free(ptr); return 0; } /* RSA-PKCS1-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_RSA) && (internalencoding == INTERNAL_ENC_PKCS1)) { dc->dec_key = RSA_new(); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_RSAPrivateKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } if (RSA_blinding_on((RSA *) kk, NULL) != 1) { free(ptr); RSA_free(kk); keynote_errno = ERROR_MEMORY; return -1; } } else { if (d2i_RSAPublicKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } free(ptr); return 0; } /* X509 Cert */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_X509) && (internalencoding == INTERNAL_ENC_ASN1) && (keytype == KEYNOTE_PUBLIC_KEY)) { if ((px509Cert = X509_new()) == NULL) { free(ptr); keynote_errno = ERROR_MEMORY; return -1; } if(d2i_X509(&px509Cert, (const unsigned char **)&decoded, len) == NULL) { free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } if ((pPublicKey = X509_get_pubkey(px509Cert)) == NULL) { free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } /* RSA-specific */ dc->dec_key = pPublicKey->pkey.rsa; free(ptr); return 0; } /* BINARY keys */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_BINARY) && (internalencoding == INTERNAL_ENC_NONE)) { dc->dec_key = calloc(1, sizeof(struct keynote_binary)); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } ((struct keynote_binary *) dc->dec_key)->bn_key = decoded; ((struct keynote_binary *) dc->dec_key)->bn_len = len; return RESULT_TRUE; } /* Add support for more algorithms here */ free(ptr); /* This shouldn't ever be reached really */ keynote_errno = ERROR_SYNTAX; return -1; }
/* Parse DER encoded asn.1 RSA public key out of a certificate stream. We reach here with 'pp' pointing to the byte after the algorithm identifier. */ int32_t psRsaParseAsnPubKey(psPool_t *pool, const unsigned char **pp, psSize_t len, psRsaKey_t *key, unsigned char sha1KeyHash[SHA1_HASH_SIZE]) { # ifdef USE_SHA1 psDigestContext_t dc; # endif const unsigned char *p = *pp; RSA *rsa; psSize_t keylen; # ifndef USE_D2I psSize_t seqlen; # endif if (len < 1 || (*(p++) != ASN_BIT_STRING) || getAsnLength(&p, len - 1, &keylen)) { goto L_FAIL; } /* ignored bits field should be zero */ if (*p++ != 0) { goto L_FAIL; } keylen--; # ifdef USE_SHA1 /* A public key hash is used in PKI tools (OCSP, Trusted CA indication). Standard RSA form - SHA-1 hash of the value of the BIT STRING subjectPublicKey [excluding the tag, length, and number of unused bits] */ psSha1Init(&dc.sha1); psSha1Update(&dc.sha1, p, keylen); psSha1Final(&dc.sha1, sha1KeyHash); # endif # ifdef USE_D2I /* OpenSSL expects to parse after the ignored bits field */ if ((rsa = d2i_RSAPublicKey(NULL, &p, keylen)) == NULL) { goto L_FAIL; } # else /* We can manually create the structures as OpenSSL would */ rsa = RSA_new(); if (getAsnSequence(&p, keylen, &seqlen) < 0 || getBig(&p, seqlen, &rsa->n) < 0 || getBig(&p, seqlen, &rsa->e) < 0) { RSA_free(rsa); goto L_FAIL; } # endif /* RSA_print_fp(stdout, rsa, 0); */ *pp = p; *key = rsa; return PS_SUCCESS; L_FAIL: psTraceIntCrypto("psRsaParseAsnPubKey error on byte %d\n", p - *pp); return PS_PARSE_FAIL; }
// ssl使用 int main() { // 1. 产生RSA密钥对 // 产生512字节公钥指数为RSA_F4的密钥对,公钥指数有RSA_F4和RSA_3两种 // 我不清楚它们的区别,就随便选定RSA_F4 // 可以使用RSA_print_fp()看看RSA里面的东西 RSA *ClientRsa = RSA_generate_key(512, RSA_F4, NULL, NULL); // --------- // 2. 从RSA结构中提取公钥到BUFF,以便将它传输给对方 // 512位的RSA其公钥提出出来长度是74字节,而私钥提取出来有超过300字节 // 为保险起见,建议给它们预留一个512字节的空间 unsigned char PublicKey[512]; unsigned char *PKey = PublicKey; // 注意这个指针不是多余,是特意要这样做的, int PublicKeyLen = i2d_RSAPublicKey(ClientRsa, &PKey); // 不能采用下面的方法,因为i2d_RSAPublicKey()会修改PublicKey的值 // 所以要引入PKey,让它作为替死鬼 // unsigned char *PublicKey = (unsigned char *)malloc(512); // int PublicKeyLen = i2d_RSAPublicKey(ClientRsa, &PublicKey); // 逐个字节打印PublicKey信息 printf("PublicKeyBuff, Len=%d\n", PublicKeyLen); for (int i=0; i<PublicKeyLen; i++) { printf("0x%02x, ", *(PublicKey+i)); } printf("\n"); // --------- // 3. 跟据上面提出的公钥信息PublicKey构造一个新RSA密钥(这个密钥结构只有公钥信息) PKey = PublicKey; RSA *EncryptRsa = d2i_RSAPublicKey(NULL, (const unsigned char**)&PKey, PublicKeyLen); // --------- // 4. 使用EncryptRsa加密数据,再使用ClientRsa解密数据 // 注意, RSA加密/解密的数据长度是有限制,例如512位的RSA就只能最多能加密解密64字节的数据 // 如果采用RSA_NO_PADDING加密方式,512位的RSA就只能加密长度等于64的数据 // 这个长度可以使用RSA_size()来获得 unsigned char InBuff[64], OutBuff[64]; strcpy((char *)InBuff, "1234567890abcdefghiklmnopqrstuvwxyz."); RSA_public_encrypt(64, (const unsigned char*)InBuff, OutBuff, EncryptRsa, RSA_NO_PADDING); // 加密 memset(InBuff, 0, sizeof(InBuff)); RSA_private_decrypt(64, (const unsigned char*)OutBuff, InBuff, ClientRsa, RSA_NO_PADDING); // 解密 printf("RSADecrypt OK: %s \n", InBuff); // ---------- // 5. 利用随机32字节Seed来产生256位的AES密钥对 unsigned char Seed[32]; // 可以采用Rand()等方法来构造随机信息 AES_KEY AESEncryptKey, AESDecryptKey; AES_set_encrypt_key(Seed, 256, &AESEncryptKey); AES_set_decrypt_key(Seed, 256, &AESDecryptKey); // ---------- // 6. 使用AES密钥对来加密/解密数据 // 注意,256位的AES密钥只能加密/解密16字节长的数据 strcpy((char *)InBuff, "a1b2c3d4e5f6g7h8?"); AES_encrypt(InBuff, OutBuff, &AESEncryptKey); memset(InBuff, 0, sizeof(InBuff)); AES_decrypt(OutBuff, InBuff, &AESDecryptKey); printf("AESDecrypt OK: %s \n", InBuff); // ---------- // 7. 谨记要释放RSA结构 RSA_free(ClientRsa); RSA_free(EncryptRsa); return(0); }
/// Attempts to load the GBv2 public key. Auth::Auth(){ const unsigned char * key = __gbv2keypub_der; pubkey = (void*)d2i_RSAPublicKey(0, &key, __gbv2keypub_der_len); }