我正在尝试了解x509证书如何与openssl和加密soap消息一起使用。我正在使用lib-wsdlpull库来修改soap消息。所以我添加了重现此示例标题的方法:http://www.ibm.com/support/knowledgecenter/SSGMCP_5.3.0/com.ibm.cics.ts.webservices.doc/wsSecurity/dfhws_soapmsg_signed.html
根据这个例子,我需要:
我有以下代码,我相信给我X.509证书
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/x509.h"
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
char *base64(const unsigned char *input, unsigned int length)
{
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char *buff = (char *)malloc(bptr->length);
memcpy(buff, bptr->data, bptr->length - 1);
buff[bptr->length - 1] = 0;
BIO_free_all(b64);
return buff;
}
/*
* generates a key pair
* */
EVP_PKEY* generateKeyPair(){
int bits = 2048; /* number of bits for the key - 2048 is a sensible value */
EVP_PKEY * pkey = EVP_PKEY_new();
RSA* rsa = RSA_new();
BIGNUM *bne = BN_new();
BN_set_word(bne, RSA_F4); /* exponent - RSA_F4 is defined as 0x10001L */
if ( RSA_generate_key_ex(rsa, bits, bne, NULL) == 0 ){
BN_free(bne);
RSA_free(rsa);
return NULL;
}
BN_free(bne);
EVP_PKEY_assign_RSA(pkey, rsa);
return pkey;
}
X509* createCertificate(){
X509* x509 = X509_new();
if ( x509 == NULL ){
return NULL;
}
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);
return x509;
}
void setPublicKey(X509* x509, EVP_PKEY* pkey){
X509_set_pubkey(x509, pkey);
}
void signCertificate(X509* x509, EVP_PKEY* pkey){
X509_sign(x509, pkey, EVP_sha1());
}
void writePrivateKey( EVP_PKEY* pkey, const char* fileName ){
FILE * f;
f = fopen(fileName, "wb");
PEM_write_PrivateKey(
f, /* write the key to the file we've opened */
pkey, /* our key from earlier */
NULL, /* default cipher for encrypting the key on disk */
NULL, /* passphrase required for decrypting the key on disk */
10, /* length of the passphrase string */
NULL, /* callback for requesting a password */
NULL /* data to pass to the callback */
);
}
void writeCertificate( X509* x509, const char* fileName ){
FILE * f;
f = fopen(fileName, "wb");
PEM_write_X509(
f, /* write the certificate to the file we've opened */
x509 /* our certificate */
);
}
const EVP_MD* digestMessage( const char* digestName, const std::string& strToEncode, unsigned char **digestValue, unsigned int& digestLen ){
const EVP_MD *digest = EVP_get_digestbyname(digestName);
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, digest, NULL);
EVP_DigestUpdate(mdctx, strToEncode.c_str(), strToEncode.size());
EVP_DigestFinal_ex(mdctx, *digestValue, &digestLen);
EVP_MD_CTX_destroy(mdctx);
return digest;
}
int main(){
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_digests();
EVP_PKEY * pkey = generateKeyPair();
if ( pkey == NULL ){
puts("Something went wrong when generating private key");
return -1;
}
X509* x509 = createCertificate();
if ( x509 == NULL ){
puts("Something went wrong when generating certificate");
return -1;
}
setPublicKey( x509, pkey );
signCertificate( x509, pkey );
writePrivateKey( pkey, "privatekey.pem" );
writeCertificate( x509, "cert.pem" );
据我所知,在cert.pem中我有X.509证书
下一步是 3.消息摘要的值。
我有以下代码
unsigned char* digestValue = new unsigned char[10000];
unsigned int digestLen = 0;
std::string textToSign = "test32131654564627863276837243286324eroi5t5twutaergeahnuihnuigyniguyfgnufutfgbuuuyggygykgygjhggyjjkjkggjhkjggjjkgjkggyjkhgyjkggyg6567578576tyuiytrfv76igrtuigrtuigbrtgrbtuuutuftffgfffff ytffhfhgfhfhgfhgfhfhgfyty54u5654u5rgu5rfguytrfrttttttyyyttgh gf";
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
textToSign += textToSign;
const EVP_MD* digest = digestMessage( "sha1", textToSign, &digestValue, digestLen );
所有我不理解和缺失的是最后一步 4.然后使用用户的私钥加密摘要值,并将其作为签名值
包含在此处我不知道处理这个问题...有人可以帮忙吗?
我写了这个
X509_digest(x509, digest, digestValue, &digestLen);
但我不确定它是否有意义......