PEM, DER, X509, ASN.1, Oh My. Where to start? [closed] - cryptography

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I'm trying to get an understanding of the world of cryptography as its practically used day to day. I'm finding it very hard to get a start footing, And I was wondering if anyone has some good resources that explain things assuming that I know nothing.
For example, I have (I believe, due to limited understanding) a file with X509 certificate and a "SignatureValue" attribute. I think these are encoded with SHA256. I would like to understand exactly what I'm looking at however, because I need to provide a "Timestamp Response File", which contains the DER representation of one Timestamp Authority Message.
Things I somewhat grasp so far:
SHA256 is a hashing algorithm. One way?
X509 is a document that defines how a certificate (whatever that is) should look
ASN.1 is a group of ways to transmit data between systems?
DER is a way of representing data in binary/octal bits.
I'd like a birds eye view of this ecosystem just so I have some concept of how this puzzle fits together, then I can delve better into the nitty gritty of How-Things-Work.

Reading whole bunch of books will take a lot of time.
Imho, the faster way would be to browse Wikipedia and read what is:
hash algorithm (in short, it transform long text/data to fixed-size value, hash, which (almost) unique represents this long text. And, yes, it is one-way.
signature algorithm - calculates something from hash value, which is called 'signature'. The main idea is that correct signature can be calculated only when you have secret key. And, this signature can be verified with public key. Public key is shared amongst people so they can verify your signatures.
So, valid signature proves that text/data was not changed by somebody else.
certificate: this is block of data, which binds user's public key to information about this key: name of the owner, email, address, whatever else. Certificate usually signed by authority (root certificate) - so, if you trust to authority, you should believe that this certificate correctly represents person.
timestamp: this is signature, made by some authority people trust to, which binds time mark to signature, made over other document. So, this will prove that this signature (and, this document) was correct at that time. This is needed since sometimes certificates can become revoked or outdated, and without timestamp you will not know if this is correct signature since you will not know when it was created.
ASN.1 - Abstract Syntax Notation, it defines text rules which describe format of some data structures. It is used in most of cryptography standards.
DER encoding (Distinguished Encoding Rules): set of rules how to encode ASN.1 objects/records to binary data. There is also BER (Basic Encoding Rules), which does almost the same, BUT it allows different encoding for the same value (like BOOL can be encoded by any non-zero value), which can not be used in cryptography since the same message can be encoded in different ways, producing different hashes.
X.509 : standard about format (ASN.1) of public-key certificates.
Hope this helps a bit to understand what's going on :)
Actually, there is a number of cryptography libraries on market, which implement all those timestamping/x.509/signing/verification,etc.

I'm sad everytime a developer has to do some "deeper" crypto stuff. I know that they are thinking that "he can write code, crypto is just a code that makes something secure, he can do it" and boy it's just wrong. Without solid or almost solid security backgroud crypto-hacking (writing own code) will fail.
I would suggest you to study it, pretty hard because if you do it right it will be ok, but if this fails and some vulnerability is introduced you will have not so nice chats. So I will suggest for starters:
Beginning-Cryptography-Java - even if you are not java person some first chapters
Handbook of applied cryptography
Applied cryptography
Security engineering
After those you would get pretty firm grass that crypto is something to be avoided, and only used with extreme caution and only when it does not introduces more problems that it solves.
And About your questions:
SHA25 - is a cryptographically secure one way hash function that produces 256bit output
X509 - describes format of digital certificates
DER and PEM are forms of certificate encodings
And my last request would be that you should not just stop on some high level "I think i got this" point of view and dig deeper and try to really understand what is and what isn't secure.

Related

Is the example proposed by Microsoft for cryptography secure enough, or should I learn more?

This is the article published by Microsoft for encrypting/decrypting data using RSA:
https://learn.microsoft.com/en-us/dotnet/standard/security/walkthrough-creating-a-cryptographic-application
As a relatively new person into the cryptography world and having read a comment on stackoverflow saying that cryptography should use a hybrid model, I researched that and it seems that hybrid models use AES and RSA for encryption and I was wondering if the example provided by Microsoft fits into the hybrid model since it uses both and if is constructed well enough and not just for novice devs just venturing into the world of cryptography.
I already have a working example where an app would encode and another would decode by loading the private key file, similar to the example.
I found an article here:
https://www.codeproject.com/Tips/834977/Using-RSA-and-AES-for-File-Encryption
He creates signatures and manifests and I'm wondering if this is what I'm looking for is Microsoft's example generally just enough, or weak?
PS: I removed the key container code and persistence as I don't want to persist or store my keys on the local machine, instead they are exported as standalone files to be stored in a DB maybe, so I'm not looking for opinions on that part at the moment.
and not just for novice devs just venturing into the world of cryptography
Well, at least it tries to define some kind of protocol, although very sparse. It also uses CBC mode (implicitly, never a good idea) and RSA with PKCS#1 v1.5 padding for encryption. Most people would opt for OAEP if RSA is used and use an authenticated cipher such as GCM.
I already have a working example where an app would encode and another would decode by loading the private key file, similar to the example.
Bad idea, the example is for file encryption, not for transport mode security, for which you need a secure transport protocol. Both the RSA implementation and CBC implementation are malleable, and are both susceptible to padding oracle attacks as well.
I don't want to persist or store my keys on the local machine
You need to establish trust, something that is missing from the example. And to establish trust you do need to persist your keys, especially if they have been randomly generated.
In the end, asking if something is secure depends on context: you need to know what your goals are and then check if the protocol provides enough protection to achieve these goals.
This is also my problem with these generic examples or wrapper classes; they make no sense to me, as the generic security that they seem to provide may not fit your use case; I'd rather design a protocol specific to the use case.

What is the difference between .CER and .CRT? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
Is there a difference between .cer and .crt. I know they both are same SSL certificate format, but don't know what is the difference between them.
If there no difference, why 2 different extensions?
None.
Extensions are useless, as are filenames. They DO NOT count. Only the content counts. The software does not care how you call your filenames, holding certificates and private keys, it could be foobar.42 and would work as well (as long as the content is correct).
The names are only to aid the humans to more easily know what it is about. It is customary for example to use the site name as filename to clearly identify it, and then use "some" extension, on one side for a certificate (.cert or .crt or .cer) and a private key (.key). You also have certificate signing requests (something you generate before getting the certificate), which are often .csr.
You may find .pem sometimes also, which is ambiguous: PEM is a format to encode a content, you can encode a certificate or a key, so just by .pem you do not know what it is about where .crt vs .key at least make the difference clear.
Now, .cert would probably be the most obvious choice... but since we inherit from some past arbitrary limits of some past OS, we often prefer 3 letters for extensions, at most, so pick your poison between shortening .cert either to .cer or .crt (the latter seems to me more often found).
Also for the same silly past arbitrary decisions, some OS attaches specific actions on specific files based on their name. Your OS may treat the same file differently if it ends in .crt vs ending in .cer. But this is all configuration and local preferences, again only the content really matters.
In a good world, where everyone can be trusted, we might not need encryption, identification, certificates and such. But such world does not exist unfortunately, bad guys are everywhere, and thus came along the need for encryption, and symmetric keys were born. 1 key that is the same for both the client and the server to encrypt & decrypt the data is all that is needed. The process is fast, as the key is usually 256 bits in length only. All good.
One concern though is, how do we distribute the key securely?
Born was the public key infrastructure system, PKI or PKIX(X for X.509), where the public key is distributed to encrypt, and the private key,(not distributed, therefore secure), to decrypt. These are called asymmetric keys, which are usually at least 2048 bits, more robust, but you guess well, slower.
Then we needed a standard to construct those keys, X.500 came along, and evolved into X.509 v3 which is encoded in either .DER(binary) or .PEM(which is just a base-64 encoding of the DER, enclosed between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----). So, sometimes, you might see .DER, sometimes .PEM certificates.
Together with .DER and .PEM, we also have other related certificates formats such as .CER and .CRT.
The difference, a good explanation taken from here:
.CRT = The CRT extension is used for certificates. The certificates
may be encoded as binary DER or as ASCII PEM. The CER and CRT
extensions are nearly synonymous. Most common among *nix systems
CER = alternate form of .crt (Microsoft Convention) You can use MS to convert .crt to .cer (.both DER encoded .cer, or base64[PEM] encoded
.cer) The .cer file extension is also recognized by IE as a command
to run a MS cryptoAPI command
Hopefully, the above has given you a background and some idea of the oh-so-many certificate extensions lying around and which can be quite confusing at times, especially for the new comer.

Is RSA-encoded data exchangable

Up to now, I thought that if I have RSA-encrypted data, this data would be easily exchangable between most platforms (.net, java, pc, unix..), because of the commonly used algorithm.
Through investigating for another questions I had, I'm now confused. I have found even between MS-implementations differences (some provider reverse the resulting byte-array). Moreover the padding seems not to follow a standardization.
Can someone with experience in cross platform cryptography give a statement, if RSA-encoded data is relatively simple exchangable (with some obvious pitfalls) or if this is a headache?
Note that RSA encryption is normally not used by itself, but in combination with a symmetric encryption algorithm.
So, to make sure to be interoperable, you need to make sure that:
Both sides use the same padding scheme for RSA (e.g. the one originally defined in PKCS#1 v1.5, or OAEP). (That does not mean that the padding has to be deterministic, just that the decrypter know which bits of the decrypted text was padding and which were the original message).
Both sides use the same format for their messages (e.g. the one in PKCS#7 or its successors).
Both sides use the same symmetric algorithm (e.g. AES-128), mode of operation (e.g. CBC) and block cipher padding scheme (e.g. PKCS#5-padding).
The encrypting party must use the public key corresponding to the private key used by the decrypting party.
The simple answer to your question is no, the cryptographic algorithm itself does not specify how to store or transmit bytes between implementations to ensure interoperability. For that you must use a standard format or protocol that gives these instructions down to the bit level. For example, in Paulo answer he talks about PKCS#7 and PKCS#1. These in turn rely on the DER-encoding rules of ASN.1 that specify exactly how to covert the big integer pieces of RSA into an unambigous sequence of bytes and back again.

How to determine the encryption scheme used when given a cipher text and the key

For a homework assignment, I am asked to determine the algorithm used to generate a given cipher text. The key is also given. Currently, I am working down a list of simple encryption algorithms and semi-blindly testing different decryption arrangements in an attempt at retrieving the given plain text.
Is there a better way to go about this process? I've read pages of Google results on the topic and haven't come across anything that explained a better process than what I'm already doing. Thus far I've run multiple levels of linguistical analysis upon the cipher text and am trying to plug in logical values into the encrypted message to decrypt it.
This is built around basic cryptographic systems, nothing at the level of public key encryption or DES.
Even if I can get the original message, how will that show the encryption scheme that was used?
My answer would be there is nothing wrong with trying various different algorithms out and seeing what works.
Cryptanalysis is like solving a puzzle, not a step by step process. You try things, you see what works, what you think gets you closer. It is absolutely trial and error based on knowledge of the potential algorithms, patterns and techniques and the reasons for them. Differential cryptanalysis, a modern technique, basically amounts to trying various combinations of keys and plaintexts within an algorithm and looking at the differences to see if you can find patterns.
From your comments, I think you're facing a vigenere cipher or some similar variant thereof. In this case, the key is important because essentially a vigenere cipher is a set of caesar ciphers and the length of the key determines the number of these ciphers. Now, the rules of the scheme in question will tell you exactly what cipher it is, but that's the basis of it.

How does password-based encryption technically work?

Say I have some data and a password, and I want to encrypt the data in such a way that it can only be recovered with the right password.
How does this technically work (i.e. how to implement this)? I often hear people use bitshifting for encryption, but how do you base that on a password? How does password-based encryption work?
An example is Mac OS X FileVault
Thanks.
If you give sample code, preferably in C, Objective-C or pseudocode.
For (symmetric) encryption you need a secret key for encryption and decryption.
Usually, the password you supply is used as the source of this key. For various security reasons, the password is not (and often cannot, due to requirements of the cipher used) directly used as the key. Instead, a key derivation function is used to generate the key from the password.
This is why passwords for encryption must be long and fairly random: Otherwise the resulting key will only come from a very small subset of possible keys, and these can then simply all be tried, thus brute-forcing the encryption.
As to code examples, there are several possibilities:
look at the source code of a crypto library, such as OpenSSL
look at the source code of a program that implements encryption, such as GnuPG
google some sample source code for a simple encryption algorithm, or a key derivation function, and try to understand it
This depends on what you want to learn.
You'll need to look to other resources for a deep explanation, as this question is extremely broad.
Speaking generally: you use a password as a "seed" for an encryption key, as sleske pointed out. Then you use this key to apply a two-way encryption algorithm (i.e. one that can be applied once to encrypt and again to decrypt). When you apply the algorithm to a piece of data, it becomes encrypted in such a way that you could never get the data back out again without using the same key, and you can't practically produce the same key without having the same password as a seed.
If you're interested in crypto, read Applied Cryptography by Bruce Schneier. Excellent read, lots of examples. It goes through many different cryptography types.
An easy way, but not exactly secure, is to rotate each byte by a number determined by the password. You can use a hash code from a string, or count the number of characters, or whatever for the number.
What you are probably thinking of, though, is public key encryption. Here is a link to a document that will tell you the math for it - you'll have to work out the implementation details yourself, but it's not that hard once you understand the math.
http://mathaware.org/mam/06/Kaliski.pdf
The basic building block of most block ciphers is a construction called a Feistel Network. It's reasonably easy to understand.
Stream ciphers are even simpler - they're essentially just pseudo-random number generators, albeit with some important security properties, where the initial internal state is derived from the key.
Password based encryption IS symmetric. The input usually consists of a salt in addition to the password. FooBabel has a cool app where you can play around with this... currently they hard code the Salt to an array of eight bytes (zero to seven) for simplicity. I put in a request to see that they let users input the salt. Anyway, here it is - PBECrypto