SWCrypt public key VS PKCS8PEM Key - ios

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.

Related

secp256k1 private key save to pem file

Hi I am doing the save private key of secp256k1 to pem file with Swift.
As I generate the private key, I got a 32 bytes key, somehow in base64 it is "7vInO7T/GBg6bxkr+6W4ESV4UOy6W4E2N4i9fBgMqYM=" which is a quite short string.
I see some example of other private key generated by other languages such as PHP or Scala I can see the private key in PEM file is somehow like this:
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIEEtespOtpvBZFfn+2YX/9WlsRLTb8YSWkfV1IBP+Lz9oAcGBSuBBAAK
oUQDQgAEun8ex7Yei3nN1mnw2/c9QNwIEzAZ8+upXkN5hgHNgrpn2ufxP8G/byc9
Lx8wKQIXhmCIXMySxUeQUCDzl65trA==
-----END EC PRIVATE KEY-----
Which is a very long string of base64.
How can I generate such long string and what the rule for it? I mean what should I do to make my quite short base64 string that I can generate to such long string as other languages do?

Decode IdToken using JJWT with RSA

My customer sends to me a JWT, I need to validate this JWT using their public key.
I am using Java and JJWT framework to validate this token.
I know decode this token using HS256, but using RS256 I don't know.
their configurations is:
Editing here to improve my question.
The jjwt example of parse that I am using:
Claims String secret = "-----BEGIN CERTIFICATE-----myx5ckey-----END CERTIFICATE-----"
byte[] dataBytes = Base64.getEncoder().encode(secret.getBytes());
byte[] byteKey = Base64.getDecoder().decode(dataBytes);
X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(X509publicKey);
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey.getEncoded())
.parseClaimsJws(idToken)
.getBody();
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
How can I validate the received token using the JWKS informations that I show? (imagem above)
I solved my problem.
String secret2 = "myX5c";
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(secret2)));
PublicKey publicKey = certificate.getPublicKey();
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey)
.parseClaimsJws(idToken)
.getBody();
#KcDoD thanks for your tips.
tldr; Need to follow three steps
Extract public key from JWK may be going through discovery document or from any other mean.
Extract JWS Signature and JWS Signing input as described by JWS specification
Pass public key, JWS signature and JWS Signing input to signature verifier
Depending on the library, step 2 and 3 may be done in single step.!
Long answer
To validate you have to follow the JWS specification.
JWS specification, defined in RFC7515 explains how to create JWT's MAC needed to validate the token. Appendix 2 of the protocol explains how to create a MAC with RS256 and validate it.
Using the discovery information, you must identify the public key. Now here you have received key details as a JWK. According JWK protocol definition on x5x,
The "x5c" (X.509 certificate chain) parameter contains a chain of one
or more PKIX certificates
So basically you have public key in the JWK. Now you need to convert the encoded String of x5x to public key. To do that, please check this already answered question.
Once the public key is constructed use it to validate the token. Following is the extraction from spec.
A.2.2. Validating
Since the "alg" Header Parameter is "RS256", we validate the
RSASSA- PKCS1-v1_5 SHA-256 digital signature contained in the JWS
Signature.
Validating the JWS Signature is a bit different from the previous example. We pass the public key (n, e), the JWS Signature (which is base64url decoded from the value encoded in the JWS representation), and the JWS Signing Input (which is the initial substring of the JWS Compact Serialization representation up until but not including the second period character) to an RSASSA-PKCS1-v1_5 signature verifier that has been configured to use the SHA-256 hash function.
To validate, its better to use a library. For reference, here is a link to how its done using nimbus

Apple Wallet NFC encryptionPublicKey

In Apple's documentation for the keys available for a Wallet pass, there's an option for a dictionary for NFC-related data. I understand that use of this key requires special permission from Apple. Regardless ...
message is straight forward -- it's the data passed to a NFC terminal (usually a unique identifier for the customer).
encryptionPublicKey, however, has me confused. Apple states it is the public encryption key used by the Value Added Services protocol. Use a Base64 encoded X.509 SubjectPublicKeyInfo structure containing a ECDH public key for group P256.
Can anyone explain what this second sentence means and/or what a developer would have to do to generate this? From what would one even generate the public/private keys?
You'll need the following to generate the public and private key. The private key is used by the merchant hardware when reading the pass and decoding the payload.
The compressed public key is what goes into your pass.json.
openssl ecparam -name prime256v1 -genkey -noout -out nfcKey.pem
openssl ec -in nfcKey.pem -pubout -out nfcPubkey.pem -conv_form compressed
cat nfcPubkey.pem
Outputs:
-----BEGIN PUBLIC KEY-----
MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/Bu9nyAtG1DQe7t7jszLb+dZ1GbX
oR8G0rIXoak67NM=
-----END PUBLIC KEY---
You'll need Base64 key (without the newline) for the encryptionPublicKey field.
E.g.
MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/Bu9nyAtG1DQe7t7jszLb+dZ1GbXoR8G0rIXoak67NM=

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

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')

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