What is the format of public key? - certificate

What is the format of public DSA key? And are all certificates are stored in base64?

Do you mean the public key format used in a certificate?
Generally, a public key in a certificate is stored in the SubjectPublicKeyInfo field (cf. RFC 5280)
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
The specifics for DSA can be found in RFC 3370. Usually the parameters of the AlgorithmIdentifier contain an instance of the Dss-Parms giving you p, k, g and the subjectPublicKey BIT STRING contains the public key y encoded as an DER-encoded INTEGER.
Concerning Base64: Strictly speaking certificates are not Base64-encoded but use an extended form of it, the PEM format, a plain text format which is the Base64 encoding of a X.509 certificate (RFC5280) enclosed between the lines
"-----BEGIN CERTIFICATE-----"
...
"-----END CERTIFICATE-----"
or
"-----BEGIN X509 CERTIFICATE----"
...
"-----END X509 CERTIFICATE----".
The certificate itself is the DER encoding of the ASN.1 structure as described in RFC 5280. See X.690 for details of DER (Distinguished Encoding Rules).
Most certificates are stored either in PEM format or directly in their raw DER-encoded form.

There is a great deal of information and references on this page for the specifications.
http://en.wikipedia.org/wiki/Digital_Signature_Algorithm

Related

Why does jwt.io show signature as valid after deleting some characters of the certificate?

Today, I have verified an JWT access token with jwt.io.
The access token is using algorithm RS256 and is digitally signed.
To verify the signature, I have put the certificate including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- in BOX1:
RSASHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
BOX1,
BOX2
)
After doing this, the status goes from red "Invalid Signature" to blue "Signature Verified" as expected.
I then accidentally deleted a character of the certificate, which left the status in blue "Signature Verified".
This made me curious, so I did some simple experiments:
After deleting some characters, it changes to red "Invalid Signature".
After deleting some more characters, it changes again to blue "Signature Verified".
This works on the last 7 lines of the certificate (certificate is 18 lines x 64 characters). In the first 11 lines, deleting a character leads to a permanently "Invalid Signature".
Is this behaviour jwt.io specific?
Or, is it expected that deleting specific characters out of a certificate leads to a still valid signature?
No, this is not jwt.io specific. First of all, the data in certificates themselves are structured using ASN.1, then encoded as binary using DER. You can see the certificate structure if you paste your base 64 into an ASN.1 decoder such as the one found here or by e.g. using openssl asn1parse.
Most of the data found in a certificate is part of the tbsCertificate structure, where TBS stands for "to be signed". Any change to that part of the certificate should result in failure as this is the part of the certificate that has been signed. This of course assumes that the signature of the certificate is indeed verified. That's generally the case unless the certificate is trusted explicitly.
If you change the signature itself then the signature verification will likely fail as well of course. But note that the signature itself is also encoded, and changes in the meta-data of the signature may not introduce a failure. This signature is present at the end of the certificate.
You may need to post the changed certificate. Otherwise we cannot tell if there is an error during verification or that the changes were only superficial.

What input is used when openssl creates digest for a file?

When I type
openssl sha256 filename.pdf
What value is used to create a digest? Is it a meta data of that file or every byte data of that pdf? I tried openssl sha256 on a large files(~2GB) and it did not take a long time, so my guess is that openssl does not use every byte in a file. So what value(byte) is used?

convert decoded pkcs12 key to pem format

I'm trying to reverse engineering an app and I'm seeing that it encrypt an string using RSA/ECB/PKCS1Padding method
before this it's loading something similar to a private key from another string with a method called "1.2.840.113549.1.12.1.3" I googled this and found out that it's a PKCS12 key
I don't have access to the codes and I'm reading this data using frida so I don't understand what’s being done actually.
What I need to do is to be able to do the same rsa encryption so I need the key for rsa
I have a sample input and output to try and test if the key is right or not. I also have a hex string which I'm guessing it’s from a pfx file, another hex string generated from the previous one which looks like a private key and another smaller hex string which might be the password for pfx (I'm not sure about this)
On further investigation I found out that class name for the key is : com.android.org.bouncycastle.jcajce.PKCS12Key
This is also the second hex string (replaced part of it with X) that I think is kind of a private key but I wasn't able to verify it :
3082035f3082035b060b2a864886f70d010c0a0103a082031430820310060a2a864886f70d01091601a0820300048202fc308202f8308201e0a00302010202106fb86aeca71187a94a49a31d57f64795300d06092a864886f70d01010b05003018311630140603550403130d524e4430382e7365702e6e6574301e170d3230303331353038353030325XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX9d4d602c133addaa58422e3af20ee97c8a9936b3134301306092a864886f70d0109153106040401000000301d06092a864886f70d01091431101e0e003700320034004e006500770000
what I tried until now :
converted the first hex string to binary and saved it into a file and then used openssl pkcs12 -in -out command to get pem formatted file, but it failed with error 4630589100:error:0DFFF0A8:asn1 encoding routines:CRYPTO_internal:wrong tag

Determine the length of a base64url encoded string

I am attempting to write a unit test to check that I'm hashing and encoding a string (actually, PEM certificate) correctly.
What I'm doing is:
Taking a certificate (in PEM format)
Convert it to DER
Run a hashing function on it to get a hashed value (SHA-1 / SHA-256)
Base64Url encoding the hash
The value of a SHA-256 hash has a constant length (256 bits). This can be represented differently (hex / binary, etc) but it's the same underneath. I'm storing the value in a Java byte array.
My question is this: if I attempt to base64url encode this hashed byte array value, is the length of the resulting encoded string always the same? Or will it vary depending on values present in the underlying hash?
What I'm not clear on is the "url" part of the "base64url" encoding: because it makes the string safe for urls, does it do any sort of character expansion (for example, urlencoding replaces a single space character with %20 which is three characters).
Base64Url encoding is simply Base64 encoding with the + and / switched to two different characters that are better for putting into a Uri.
Since SHA-256 will always be the same fixed length, a base64-encoded SHA-256 hash will also be that same fixed length. Each base64 digit is 6 bits. While you will get some padding characters ('=') due to 256/6 not being an integer, the string will always be the same length.

Can extensions .pem and .crt be used interchangeably?

I have an authority certificate generated in PEM encoding. Does it mean I can call it both ca.pem and ca.crt? Can .crt and .pem mean the same thing? Or are they actually different formats?
To a file, file names and extensions don't matter.
Windows does maintain an association of extensions to semantic types (and semantic types to what-to-do-with-this), which is the ftype/assoc system.
C:\>assoc .cer
.cer=CERFile
C:\>ftype CERFile
CERFile=%SystemRoot%\system32\rundll32.exe cryptext.dll,CryptExtOpenCER %1
We can also ask "What are all of the associations?", and filter that:
C:\>assoc | findstr CERFile
.cer=CERFile
.crt=CERFile
.der=CERFile
So Windows will treat any of .cer, .crt, and .der the same.
PEM, on the other hand, is not a default association:
C:\>assoc .pem
File association not found for extension .pem
In general, a ".pem" would suggest that it is some data in the Privacy Enhanced Mail (PEM) format, which is
(Beginning of file or a newline)
5 hyphens
BEGIN
a space
One or more characters ending in not-a-space
5 hyphens
A newline
Base64 data, formatted 64 characters to a line
A newline
5 hyphens
END
a space
The same string as in BEGIN
5 hyphens
Newline or end-of-file
The word(s) identify the data format, which is then used by the reader. For a certificate, for example, that's "BEGIN CERTIFICATE".
Certificates really are defined in a binary syntax called DER (Distinguished Encoding Rules (for ASN.1 data)). Certificate processors ultimately need the binary data (which is what got base64-encoded), but they can differ on whether they expect DER or PEM data. To many Windows APIs the certificate can be presented in either form and the underlying system content sniffs to figure out which format the data is in.
There's no real standard or heuristic for if .cer, .crt, or .der is PEM or DER data; though one would sort of expect .der to be DER :). (But lots of things are DER-encoded; not just certificates)
Does it mean I can call it both ca.pem and ca.crt?
If you're loading things by filename, it probably doesn't matter. If you're using OpenSSL commandline tools it definitely doesn't matter (but they want the data to be PEM encoded by default).
If you're on Windows and you want double-clicking to work, you want .cer or .crt.