ruby encode a p12 certificate(binary) and send as a json response - ruby-on-rails

I have a pem certificate with a private key.
I am using the above information to generate a p12 certificate which is password protected as follows:
def p12_cert
ca_cert = x509_cert(File.open("#{root}/ca-cert.crt").read)
p12 = OpenSSL::PKCS12.create(#random_pass, 'My Certificate',
rsa_pkey(private_key), x509_cert(public_cert), [ca_cert])
create_file('p12', p12.to_der, ':ASCII-8BIT')
end
The issue is this is in binary format and cannot be transmitted via a json API.
Can someone how me how to encode it(maybe base64) so that this can be sent as a JSON response?
EDIT: I opened the p12 file for read and then tried to base64 encode, got the following:
irb(main):017:0> enc_p12 = Base64.encode64(p12) TypeError: no implicit
conversion of OpenSSL::PKCS12 into String

You don't usually encode the PKCS12 object itself but the raw file. Something like
Base64.encode64( File.read(filename, mode: 'rb')

Related

How to encrypt payload using jwe and sign the encrypted payload with jws in ruby?

i have to use alg: 'RSA-OAEP', enc: 'A256GCM' in jwe and want to sign encrypted payload with alg :PS256....i have certificate and private key as well

In Ruby, how do I verify a signature that is based off of data that has been SHA256 hashed and then base 64 encoded before signing?

I am trying to port java code that verifies a signature. To generate said signature, a string is first hashed with a SHA-256 digest, then base64 encoded then signed.
The Java code to verify the signature:
public static boolean ver(X509Certificate cert, String data, String sig) throws Exception {
byte[] hashOnly = MessageDigest.getInstance("SHA-256").digest(
data.getBytes(StandardCharsets.UTF_8)
);
String hashWithEncode = Base64.getEncoder().encodeToString(hashOnly);
byte[] encodedDataBytes = hashWithEncode.getBytes();// Byte array of payload that is signed
byte[] decodedSignature = Base64.getDecoder().decode(sig);// Get byte[] of signature string from payload
Signature verifier = Signature.getInstance("SHA256withRSA");
verifier.initVerify(cert.getPublicKey());
verifier.update(encodedDataBytes);
return( verifier.verify(decodedSignature) );
}
Note the data is first hashed, then encoded, then the signature is verified. This will correctly verify a signature
My Ruby code is:
def ver(cert, signature, data)
pub_key = cert.public_key
digest = OpenSSL::Digest::SHA256.new
decoded_sig = Base64.decode64(signature)
ver = pub_key.verify(digest, decoded_sig, data)
end
which will not verify the same signature and data.
The output of
OpenSSL::Digest::SHA256.base64digest(data)
will match hashWithEncode from the Java code, but I do not understand how to pass this value to the signature verification, rather than only the SHA256 hash, as you cannot specify the base64 encoding output in the Digest object required for the verify method.

Attach s3 object to SendGrid Email

I'd like to attach an image from s3 to a sendgrid email. Ideally there is no need to save the file on disk. How can I convert an object in s3 to a base64 encoded string?
file = s3.get_object(bucket: "my_bucket",
key: "key"
)
obj = {
content: file.body.read,
filename: "file_name"
}
Note that the file is a StringIO object. This code also throws the following error JSON::GeneratorError: source sequence is illegal/malformed utf-8
How can I convert an object in s3 to a base64 encoded string?

SWCrypt public key VS PKCS8PEM Key

I want to user SWCrypt for RSA encryption and decryption. i should send my public key base64 decoded to server. but when i try send generated public key base64 i can't get this error in server side:
let (privateKey, publicKey) = try CC.RSA.generateKeyPair(2048)
let publicKeyBase64 = publicKey.base64EncodedString()
error: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
but when send PEMPublicKey getting successfully response.
let publicKeyPEM = SwKeyConvert.PublicKey.derToPKCS8PEM(publicKey)
what is difference between publicKeyBase64 and publicKeyPEM?
sample of generated key:
MIIBCgKCAQEAuWwCZpNXJtT2spBsDwrQaTFGVAjicM341Qzg+1whtlj9J60c/7HYe6AcGHa8Dinkiuk7Whs1Wpa34aa223WQsa+kFSNwkC6oDUXhewan3VEsv1uedzHc8JPlTXnItJsP8cIETFgHpdKWk462hU09mVCTtQTix0BEb8snS96wERvKq957OeaGtFasfT/bQfY0mbDu6eEMqswmfX8j84kuTfwWtqt6mLMTJaDwnsGc5WY1zkau68IQ/CBiiLpZ5hSVMs2pPj3Ao0+wNhR5MlMgdcwrU62SHWcMJ5cYssFgWZyZSvO3n/yW43fE5a1i+9Tm2trveGIdMR4d/MoA79/8IQIDAQAB
sample of generated PEM key :
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuWwCZpNXJtT2spBsDwrQaTFGVAjicM341Qzg+1whtlj9J60c/7HYe6AcGHa8Dinkiuk7Whs1Wpa34aa223WQsa+kFSNwkC6oDUXhewan3VEsv1uedzHc8JPlTXnItJsP8cIETFgHpdKWk462hU09mVCTtQTix0BEb8snS96wERvKq957OeaGtFasfT/bQfY0mbDu6eEMqswmfX8j84kuTfwWtqt6mLMTJaDwnsGc5WY1zkau68IQ/CBiiLpZ5hSVMs2pPj3Ao0+wNhR5MlMgdcwrU62SHWcMJ5cYssFgWZyZSvO3n/yW43fE5a1i+9Tm2trveGIdMR4d/MoA79/8IQIDAQAB
how can send generated public key simple of PEM key format?
thanks.
X509 is a standard for Public Key Infraestructure, not a encoding format. You can encode a X509 public key in PEM (base64), DER(binary) or XML. Also the binary data of the public key can be represented in PCKS#1 or X509 SubjectPublicKeyInfo.
In my knowledge PKCS#8 is a standard for private keys. See PKCS #8: Private-Key Information Syntax Standard. So I guess SWCrypt is really using X509 SubjectPublicKeyInfo (Maybe i have not read some RFCs), which is what your server is waiting for.
let publicKeyPEM = SwKeyConvert.PublicKey.derToPKCS8PEM(publicKey)
SubjectPublicKeyInfo encapsulates the public key into a ASN.1 structure adding a header. If you encode the raw data of the public key (DER) using publicKey.base64EncodedString, that header is not added and your server does not know how to manage it.

Convert NSData to PEM to Sign Certificate in Node.js

I am creating a CSR using this library on iOS and then encoding it as Base 64.
https://github.com/ateska/ios-csr
The library creates the CSR as NS Data on iOS.
I am able to send this data to my Node.JS server. I want to convert this to a PEM so that I can sign this CSR using the server's private key. Does anyone know how to do this?
Thanks
With SCCCSR from ios-csr library you will have a certificate request in PKCS#10 format, encoded in binary
let certificateRequest = sccsr.build(publicKey, privateKey: privateKey)
A PEM format requires a conversion to Base64 and around with the -----BEGIN CERTIFICATE REQUEST----- and -----END CERTIFICATE REQUEST----- headers
let certificateRequestB64 = certificateRequest.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
let certificateRequestPEM =
"-----BEGIN CERTIFICATE REQUEST-----\\n" + certificateRequestB64 + "\\n-----END CERTIFICATE REQUEST-----\\n"

Resources