ecc public key initialization and signature check - public-key-encryption

I'm trying to use Crypto++ to initialize a public key only and use it to verify a signature.
An external chip creates a signature of a message using its private key (K283 aka sect283k1) (invisible for me).The signature has the format of 72 bytes (36 R and 36 S coordinate) concatinated to a single signature messege.
The public key is available as 72 byte X and Y coordinate. When i use the internal key pair creator in crypto++ , the verification works. But if i try to initialize the public key only, the verification fails.
Does anyone know how to properly initialize an ECC public key in crypto++ ?

Related

Decryption using AES

Using AES library i am trying to send encrypted data from arduino side to raspberry pi side.The encrypted data that is being printed on the arduino serial monitor is not the same as what is being printed on the raspberry side.
Maybe it is the decoding problem.
Also while decrypting on the raspberry pi side it gives an error saying "the input text must be multiple of 16 in length", when i pad the input( temperature data) with zeroes it still gives the same error message.
I have tried using 'utf-8' and 'iso-8859-1' for decoding but still it doesnt show the same decrypted data.
PYTHON CODE :
from Crypto.Cipher import AES
ser=serial.Serial(' /dev/ttyS0',9600)
st=ser.readline()
st1=st.decode('utf-8')
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
ciphertext = obj.encrypt(message)
obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
obj2.decrypt(ciphertext)
ARDUINO CODE :
void aesTest (int bits)
{
aes.iv_inc();
byte iv [N_BLOCK] ;
int plainPaddedLength = sizeof(chartemp) + (N_BLOCK - ((sizeof(chartemp)-1) % 16));
byte cipher [plainPaddedLength];
byte check [plainPaddedLength];
aes.set_IV(myIv);
aes.get_IV(iv);
aes.do_aes_encrypt(chartemp,sizeof(chartemp),cipher,key,bits,iv);
aes.set_IV(myIv);
aes.get_IV(iv);
aes.printArray(cipher,(bool)false); //print cipher with padding
String cipher1=String((char*)cipher);
myserial.println(cipher1);
}
HERE chartemp is the temperature that from LM35 IC converted to characted array.
I expect the output on the raspberry pi side to be decrypted properly
Encrypted data is a sequence of pseudo-random bytes. It is not a valid UTF-8 string.
This line is a bit dodgy, but probably technically "works:"
String cipher1=String((char*)cipher);
But this line is incorrect:
st1=st.decode('utf-8')
You can't take random data and decode it as utf-8. You either need to send and receive the data as just a string of bytes, or encode the data into a string, such as with Base64. I suspect you'll be more comfortable with the latter, so look at Base64 in Java and base64 in Python.

DEX LDAP connector token signing

I am playing around with DEX and openldap. When I get a token back in my browser and put it into JWT debugger with the public key i generated, it doesn't verify the signature. I am trying to step through the code of DEX, but the debugging tools are not really working on my computer. I have resorted to log statements. I can't really find where I can observe the signing of the token to see if the program is using the keys i provided or not. Which function actually signs the token and how can I observe what key it uses to sign?
The key can be read from the DEX "keys" endpoint which can be obtained from:
http://your.dex.com/.well-known/openid-configuration
Typically, it would be something like:
http://your.dex.co/keys
After that, the public keys can be extracted using the following program:
https://play.golang.org/p/wVusucNGDI
One of those keys will be able to validate the token:
from jose import jwt
key = '''-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArT9AtIlC8MxhLYhz8ODH
...
+QIDAQAB
-----END PUBLIC KEY-----'''
encoded = 'eyJh...ocw'
audience = ''
if audience == "":
opts = {"verify_aud": False}
else:
opts = {}
opts['verify_at_hash'] = False
decoded = jwt.decode(encoded, key, audience=audience, options=opts)
print(decoded)

Installing a java card applet fails due to RSA keypair generation

I'm trying to install an applet into a J3A040 JCOP card.
As install method I have the following:
protected MainApplet() {
try {
// CREATE RSA KEYS AND PAIR
m_keyPair = new KeyPair(KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_2048);
// STARTS ON-CARD KEY GENERATION PROCESS
m_keyPair.genKeyPair();
// OBTAIN KEY REFERENCES
m_publicKey = (RSAPublicKey) m_keyPair.getPublic();
m_privateKey = (RSAPrivateKey) m_keyPair.getPrivate();
} catch (CryptoException c) {
//this line will give you the reason of problem
short reason = c.getReason();
ISOException.throwIt(reason); // for check
}
register();
}
The installation always fails with the following error:
pro.javacard.gp.GPException: Install for Install and make selectable failed SW: 6A80
at pro.javacard.gp.GlobalPlatform.check(GlobalPlatform.java:1092)
at pro.javacard.gp.GlobalPlatform.installAndMakeSelectable(GlobalPlatform.java:798)
at pro.javacard.gp.GPTool.main(GPTool.java:478)
However, if I remove the keypair generation, everything works fine.
I have read the card specifications and it stands:
. RSA and RSA CRT (1280 up to 2048 bits keys) for en-/decryption and
signature generation and verification1 d. RSA CRT key generation (1280
up to 2048 bits keys) in a secured environment
I guess it shouldn't be a problem.
Any guesses?
The problem is caused by an invalid cast: you asked for an RSA KeyPair with the private key in the Chinese Reminder Theorem format (ALG_RSA_CRT).
That is why the getPrivate() method does not return an RsaPrivateKey instance, but an RsaPrivateCrtKey instance. Casting to RsaPrivateKey causes the 6A80 status word.
So you should either use the standard algorithm:
m_keyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
, or use a correct cast:
m_publicKey = (RSAPublicKey) m_keyPair.getPublic();
m_privateKey = (RSAPrivateCrtKey) m_keyPair.getPrivate();

Calculate an RFC 2104-compliant HMAC with the SHA256 hash algorithm in ruby

I was going through the Amazon Product Advertising API REST signature docs and I got stuck at #8
Calculate an RFC 2104-compliant HMAC with the SHA256 hash algorithm using the string above with our "dummy" Secret Access Key: 1234567890. For more information about this step, see documentation and code samples for your programming language.
I managed to get it on one more try with the help of Calculating a SHA hash with a string + secret key in python.
The following creates the correct signature:
require 'openssl'
secret_key = '1234567890'
query = 'AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReviews&Service=AWSECommerceService&Timestamp=2009-01-01T12%3A00%3A00Z&Version=2009-01-06'
data = ['GET', 'ecs.amazonaws.com', '/onca/xml', query].join("\n")
sha256 = OpenSSL::Digest::SHA256.new
sig = OpenSSL::HMAC.digest(sha256, secret_key, data)
signature = Base64.encode64(sig)
Adding to AJcodez answer:
I would do:
...
signature_raw = Base64.strict_encode64(sig)
signature = CGI::escape(signature_raw)
encode64adds a newline at the end, strict_encode64() does not.
https://stackoverflow.com/a/2621023/2760406
Amazon wants you to "URL encode the plus (+) and equal (=) characters in the signature" #9 - won't work now if you don't.
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html#rest_detailedexample
You can calculate a keyed-hash message authentication code (HMAC-SHA256) signature with your secret access key by using cryptoJs
First install cryptoJs locally in your system by typing
npm install crypto-js
to install it globally you node a flag -g to the above command. Then add this code and run it.
var CryptoJS = require("crypto-js");
// Calculate an RFC 2104-compliant HMAC with the SHA256 hash algorithm
var exampleString =
"GET\n" +
"webservices.amazon.com\n" +
"/onca/xml\n" +
"AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers%2CReviews&Service=AWSECommerceService&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01";
var signature = CryptoJS.HmacSHA256(exampleString, "1234567890");
console.log("test signature", signature.toString(CryptoJS.enc.Base64));

Which privatekey format is this?

I've a private key made with OpenSSL and encrypted with RSA like this:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQILJ8rNTk54VICAggA
MBQGCCqGSIb3DQMHBAiXuThuf12hMwSCBMhrm8H2j7yzLBOIvSWbLoyUmIn7e9zA
6PLDzj1dos+h+wAkPN0IgJlkdoBBXlnF7tzGdoctOYOKiu/p+HLzMnvHaDfNSFwz
5zx4yyZsKtf90gT6IVuJy7TMiLK3gk4gdZJc820OeRr1FjdRV3iVpTXbVfpwG/B3
IbV0PX3ZaHeR1m8vWI0/XQB7ZL7lLT+3MO66X/PAMTPA9joFMxuPFasIb2uXSqe/
CJNOyY4iW89uYHFiOe53e4ggUdT/rupoR4OSNKKEH5f1y+FIuH1xNvlmi14hJn+k
KOOi89vVIcvh4abCM+jhYwpPOGB8Sz2bAXsYocgZPvKtKakHlis7RcSsd5Usx9Nt
tgQ=
-----END ENCRYPTED PRIVATE KEY-----
And I've stored it into a user.key file.
Actually I'm implementing a CMS encrypt and decrypt project in objective-c. Now I'm trying to decrypt my encrypted container file using certificates, private key, and so on...
I'm a little bit confused which method from OpenSSL I should choose to load the aforementioned key into an EVP_PKEY object.
It suggests me the following formats:
FORMAT_ASN1
FORMAT_PEM
FORMAT_PKCS12
FORMAT_MSBLOB
FORMAT_PVK
I know that it's not PEM and PKCS12. I would guess ASN1 or PVK but I really don't know and I haven't found any further information on this in the OpenSSL docu.
Can anyone tell me please which format the aforementioned key has?
EDIT:
To specify my question a bit more: I have the aforementioned key loaded into a BIO. I can read this BIO with BIO_read(keybio, ...) successfully and it contains the key (in ascii). Now I want to get an EVP_PKEY from this BIO.
I've tried...
EVP_PKEY *key = PEM_read_bio_PrivateKey(keybio, NULL, 0, NULL);
... but this doesn't work. When I call this it asks me to enter the passphrase in the console and when I do this, the key is NULL. :-/
The key is a PKCS#8 EncryptedPrivateKeyInfo wrapped in a PEM-container.
You can do something like this to get it into an EVP_PKEY-object:
// This must be called once:
OpenSSL_add_all_algorithms();
BIO* bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
X509_SIG* p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
if(p8==NULL){
BIO_printf(bio_err, "Error decoding key\n");
ERR_print_errors(bio_err);
return;
}
PKCS8_PRIV_KEY_INFO* p8inf = PKCS8_decrypt(p8, password, strlen(password));
if(p8inf==NULL){
BIO_printf(bio_err, "Error decrypting key\n");
ERR_print_errors(bio_err);
return;
}
EVP_PKEY* pkey = EVP_PKCS82PKEY(p8inf);
if(pkey==NULL){
BIO_printf(bio_err, "Error converting key\n");
ERR_print_errors(bio_err);
return;
}
That (extended) PEM format is used by OpenSSL for PKCS#8 encoded private keys.

Resources