Skip to content

Instantly share code, notes, and snippets.

@sakamoto-poteko
Created September 22, 2017 10:48
Show Gist options
  • Save sakamoto-poteko/49ff059874d03e93e22f1b2a61180371 to your computer and use it in GitHub Desktop.
Save sakamoto-poteko/49ff059874d03e93e22f1b2a61180371 to your computer and use it in GitHub Desktop.
OpenSSL ECDSA signing and verification
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <vector>
#include <openssl/ecdsa.h>
#include <openssl/sha.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
bool verifyECDSA(const std::vector<std::uint8_t> &message,
const std::vector<std::uint8_t> &signature)
{
FILE *file = std::fopen("ec.crt", "r");
X509 *x509 = PEM_read_X509(file, NULL, NULL, NULL);
EVP_PKEY *evp_pubkey = X509_get_pubkey(x509);
EC_KEY *ecdsa_pubkey = EVP_PKEY_get1_EC_KEY(evp_pubkey);
std::uint8_t dgst[32];
SHA256_CTX shactx;
SHA256_Init(&shactx);
SHA256_Update(&shactx, message.data(), message.size());
SHA256_Final(dgst, &shactx);
int result = ECDSA_verify(0, dgst, sizeof(dgst), signature.data(), signature.size(), ecdsa_pubkey);
std::cout << "Signature is " << (result == 1 ? "valid" : "invalid") << std::endl;
EC_KEY_free(ecdsa_pubkey);
EVP_PKEY_free(evp_pubkey);
X509_free(x509);
std::fclose(file);
return result == 1;
}
bool signECDSA(const std::vector<std::uint8_t> &message,
std::vector<std::uint8_t> &signature)
{
bool _signed = false;
FILE *file = std::fopen("ec.key", "r");
EC_KEY *ecdsa_privkey = nullptr;
PEM_read_ECPrivateKey(file, &ecdsa_privkey, NULL, NULL);
std::uint8_t dgst[32];
SHA256_CTX sha256ctx;
SHA256_Init(&sha256ctx);
SHA256_Update(&sha256ctx, message.data(), message.size());
SHA256_Final(dgst, &sha256ctx);
unsigned int buflen;
buflen = ECDSA_size(ecdsa_privkey);
std::uint8_t *buffer = (std::uint8_t *)OPENSSL_malloc(buflen);
if (!ECDSA_sign(0, dgst, 32, buffer, &buflen, ecdsa_privkey)) {
goto signECDSA_free;
}
signature.resize(buflen);
std::memcpy(signature.data(), buffer, buflen);
_signed = true;
signECDSA_free:
EC_KEY_free(ecdsa_privkey);
std::fclose(file);
OPENSSL_free(buffer);
return _signed;
}
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
const int MSG_SIZE = 32;
std::vector<std::uint8_t> msg;
msg.resize(MSG_SIZE);
for (int i = 0; i < MSG_SIZE; ++i) {
msg[i] = (i % 26) + 'a';
}
std::vector<std::uint8_t> signature;
bool _signed = signECDSA(msg, signature);
if (_signed) {
std::cout << "Message signed" << std::endl;
} else {
std::cout << "Message not signed" << std::endl;
return 1;
}
bool verified = verifyECDSA(msg, signature);
if (verified) {
std::cout << "Message verified" << std::endl;
} else {
std::cout << "Message verification failed" << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment