What is this data format "5540 6EA5 0709 24DF A45C 5BF3 AE5A 4350 BC40 6988" - pgp

I am a little baffled, I cannot get my brain into gear to pin point what these data format the following is:
5540 6EA5 0709 24DF A45C 5BF3 AE5A 4350 BC40 6988
Any ideas ?
I think the consensus it that the above is a PGP key

Not sure but looks like Google diverter PGP keys

The data is a base16-encoded 20-byte sequence. While it can be anything, the most likely is an SHA1 hash of something (maybe of the PGP key). This is definitely not the key itself, because PGP keys are long (hundreds of bytes). Thus other answers are misleading.

As you have found it on a business card, then it is PGP key for sure. Was there any QR code in the business card. Basically PGP keys on business cards are used to download vCard using QR Code.

Related

Implementing key derivation properly as suggested by OpenSSL for crypto.createCipher() of "Crypto" library(nodejs)

I am fixing this issue. Reading the issue will give you a better picture of the problem, nonetheless I'm writing the issue here in my own language here.
This is how system should work:
User inputs text and a password, it gets saved in a file after strong encryption. When user inputs encryptedText and password, it returns the decrypted text. Currently the encryption is handled using Crypto library of node.js, function used createCipher.
Problem: The solution works very well with createCipher but it does not employ any kind of salt mechanism. Openssl recommends to use use pbkdf2 for deriving keys. I understand why it is necessary, because otherwise encrypted value of a text will be same always(e.g. encryption of "1234" with the same password will always result in "xyz"), which makes rainbow table attack easy/possible.
Solution I'm trying: I started implementing Openssl's suggestion to have key derivation mechanism using pbkdf2, but I'm not quite able to grasp how should it be done properly. Please help me understand and figure out the right approach for this issue. I am thinking of following approach but a lot of things seem to be missing
deriveKey(password) : create hash for the password string using a random salt and any hashing algo("sha256" probably), iterations = 64000.
derivedKey = crypto.pbkdf2Sync(password, salt=crypto.randomBytes(256), iterations, 512, 'sha256',...)
encrypt(text, derivedKey, cb):
Create cipherObject using derivedKey:
cipherObject = createCipheriv(algo="aes-256-cbc", derivedKey, iv2=randomBytes(256),...)
Apply encryption:
cipherText = cipherObject.update(text,...)
Store encryptedText:
1:salt;iters:IV:cipherText in a file locally (thanks to #bartonjs for making me understand this)
decrypt(encryptedText, password):
So the text to decrypt looks like this: 1:salt;iters:IV:cipherText
Get derived from the saved configuration:
derivedKey = pbkdf2Sync(password, salt, iters, 'sha256')
Create decipher object with the same algo and above derivedKey: decipherObject = createDecipherIv("aes-256-cbc", derivedKey, IV...)
update decipherObject to get finally the original text:
text = decipherObject.update(cipherText,...)
My 3 big questions in order of priority
Am I doing everything right conceptually?
Is there any security concern that I need to think of?
Am I following the best practices? What could be improved.
P.S. I'm not an expert of cryptography, would be helpful to get opinion from one
For decryption I think I will have to save salt of derivedKey as well with iv. I don't know if that would compromise the security or not. What should be the solution?
A salt, from the NIST glossary:
A non-secret value that is used in a cryptographic process, usually to
ensure that the results of computations for one instance cannot be reused by an Attacker.
SOURCE: SP 800-63; CNSSI-4009
Since it's defined as a "non-secret" value, writing it next to the IV does not compromise security.
Note that you also should write the iteration count for PBKDF2.
salt;iters:IV:cipherText
("Startup", "IV", "ciphertext" separated by colons, and startup is broken into "salt" and "iteration count" by a semi-colon, so parsing isn't ambiguous as the structure evolves... for best results, something in the beginning would be a "schema value", like the number 1, for v1 of your file format, like 1:salt;iters:IV:cipherText).
I'm assuming you don't want to implement it yourself if you don't have to. And as CodeCaster said, if you don't have solid knowledge of it, you really shouldn't be the one implementing it.
My suggestion is to use the Stanford Javascript Encryption Library (sjcl) which has support for pbkdf2.
Check out their demo page, which allows you to encrypt a message with a password and a random salt:
https://bitwiseshiftleft.github.io/sjcl/demo/
And here's a link to the demo source, which should give you an idea of how to implement it with their library:
https://github.com/bitwiseshiftleft/sjcl/blob/master/demo/example.js
Edit (bumping from the comments to an answer) As josh3736 pointed out in the comments, no third-party library is necessary. Node's crypto module natively supports pbkdf2. He provided the following link as an example:
https://cafedev.org/article/2016/06/secure-text-encryption-with-nodejs/

How to securely encrypt many similiar chunks of data with the same key?

I'm writing an application that will require the following security features: when launching the CLI version, you should pass some key to it. Some undefined number of chunks of data of the same size will be generated. It needs to be stored remotely. This will be a sensitive data. I want it to be encrypted and accessible only by that one key that was passed to it initially. My question is, which algorithm will suit me? I read about AES but it says that
When you perform an encryption operation you initialize your Encryptor
with this key, then generate a new, unique Initialization Vector for
each record you’re going to encrypt.
which means I'll have to pass a key and an IV, rather than just the key and this IV should be unique for each generated chunk of data (and there is going to be a lot of those).
If the answer is AES, which encryption mode is it?
You can use any modern symmetric algorithm. The amount of data and how to handle your IVs is irrelevant because it applies no matter which symmetric algorithm you pick.
AES-128 is a good choice, as it isn't limited by law in the US and 128 bits is infeasible to brute force. If you aren't in the US, you could use AES-256 if you wanted to, but implementations in Java require additional installations.
You say you are going to generate n many chunks of data (or retrieve, whatever).
You could encrypt them all at once in CBC mode, which keeps AES as a block cipher, and you'll only end up with one IV. You'll need an HMAC here to protect the integrity. This isn't the most modern way, however.
You should use AES in GCM mode as a stream cipher. You'll still have one single IV (nounce) but the ciphertext will also be authenticated.
IVs should be generated randomly and prepended to the ciphertext. You can then retrieve the IV when it is time to decrypt. Remember: IVs aren't secret, they just need to be random!
EDIT: As pointed out below, IVs should be generated using a crypto-secure random number generator. IVs for CTR based modes, like GCM, only need to be unique.
In summary, what you are worried about shouldn't be worried about. One key is fine. More than one IV is fine too, but there are ways to do it with just one. You will have to worry about IVs either way. Don't use ECB mode.

How Do You Ensure Data Security of Small Data?

My Question:
What is the Best Approach to Ensure Data Security of Small Data? Below I present a concern around symmetric and asymmetric encryption. I'm curious if there is a way to do asymmetric encryption on small data with an equivalent of some sort of "salting" to actually make it secure? If so, how do you pick a "salt" and implement it properly? Or is there a better way to handle this?
Explanation of My Concern:
When encrypting something that has "bulk" it seems to me that asymmetric encryption approaches are pretty secure. My concern is around if I have a small field of data, say a credit card number, password, or social security number in a database. Then the data being encrypted is of fixed length and presentation. That being said, a hacker could attempt to encrypt every possible social security numbers (10^9 permutations) with the public key and compare it to values stored in the db. Once they find a match, they know the real number. Similar attacks can be done for the other data types. Because of this, I decided to avoid symmetric methods like mysql's AES_ENCRYPT() built in function, however now I'm questioning asymmetric as well.
How do we properly protect small data?
Salting is normally used for hash algorithms, but I need to be able to get the data back after. I thought about maybe having some "base bulk text", then append the sensitive data to the end. Do the encrypt on that concatenation. Decryption would reverse the process, by decrypting then stripping off the "base bulk text". If the hacker can figure out the base bulk text then I don't see how this would add any additional security.
Picking other data to include as part of encryption, to help act like a salt value derived from other fields in the database(or hash values of those fields, or combination there of yields the same issue) also seems like it is vulnerable. As hackers could be run through combinations similar to the attack mentioned above to try to perform a more intelligent form of "brute force". That being said, I'm unsure of how to properly secure the small data and my googles have not helped me.
What is the best approach to ensure data security of small data?
If you are encrypting with an RSA public key, there is no need to salt the small data. Use OAEP padding. The padding introduces the equivalent of random salt. Try it: encrypt the credit card number twice with the same RSA public key, using OAEP padding, and look at the result. You will see two different values, indistinguishable from random data.
If you are encrypting with an AES symmetric key, then you can use a random IV per data, and store the IV in the clear, publicly, next to the ciphertext. Try encrypting the credit number twice with AES CBC mode, for example, with a unique, 16 byte (cryptographically strong) IV each time. You will see two different ciphertexts. Now, assuming a 16-byte AES key, try to brute force those two outputs, without using any knowledge of the key. Use just the ciphertext, and the 16 byte IVs, and try to discover the credit card number.
EDIT: It's beyond the scope of the question, but since I mention it in the comment, if a client can send you arbitrary ciphertext to decrypt ("decrypt this credit card info"), you must not let the client see any difference between a padding error on decryption, vs. any other error on decryption. Look up "padding oracle".
If you need to encrypt data use a symmetric key algorithm, AES is a good choice. Use a mode such as CBC and a random IV, this will ensure that encryption the same data will produce different output.
Add PKCS#7 née PKCS#5 for padding.
If there is real value in the data hire a cryptographic domain expert to help with the design and later validation.
Asymmetric encryption is most useful for communicating encrypted data between two parties. For example, you have a mobile application that accepts credit card numbers and needs to transmit them to the server for processing. You want the public application (which is inherently insecure) to be able to encrypt the data and only you should be able to decrypt it in your secure environment.
Storage is a completely different matter. You're not communicating anything to or from an insecure party, you are the only one dealing with the data. You don't want to give everyone a way to decrypt things if they breach your storage, you want to make things as difficult as possible. Use a symmetric algorithm for storage and include a unique Initialization Vector with each encrypted value as a hurdle to decryption if the storage is compromised.
PCI-DSS requires that you use Strong Cryptography, which they define as follows.
At the time of publication, examples of industry-tested and accepted standards and algorithms for minimum encryption strength include AES (128 bits and higher), TDES (minimum triple-lengthkeys), RSA (2048 bits and higher), ECC (160 bits and higher), and ElGamal (2048 bits and higher). See NIST Special Publication 800-57 Part 1 (http://csrc.nist.gov/publications/) for more guidance on cryptographic key strengths and algorithms.
Beyond that, they are primarily concerned with key management, and with good reason. Breaching your storage won't help as much as actually having the means to decrypt your data, so ensure that your symmetric key is managed correctly and in accordance with their requirements.
There is also a field of study called Format-preserving encryption which seeks to help legacy systems maintain column-width and data types (a social security number is a 9-digit number even after encryption, etc), while allowing values to be securely encrypted. In this way the encryption can be created at a low level of the legacy system without breaking all of the layers above it which depend on a particular data format.
It is sometimes called "small-space encryption" and the idea is also explained in the paper How to Encipher Messages on a Small Domain
Deterministic Encryption and the Thorp Shuffle which gives an introduction to the topic and presents a specific algorithm devised by the authors. The Wikipedia article mentions many other algorithms with similar purpose.
If you'd prefer a video explanation of the topic, see The Mix-and-Cut Shuffle: Small Domain Encryption Secure Against N Queries talk from Crypto 2013. It includes graphics detailing how several algorithms work and some early research into the security of such designs.
When I encrypt short messages, I add a relatively long random salt to them before encryption. Edit others suggest prepending the salt to the payload.
So, for example, if I encrypt the fake credit card number 4242 4242 4242 4242. what I actually encrypt is
tOH_AN2oi4MkLC3lmxxRWaNqh6--m42424242424242424
the first time, and
iQe5xOZPIMjVWfrDDip244ZGhCy2U142424242424242424
the second time, and so forth.
This random salting significantly discourages the lookup table approach you describe. Many operating systems furnish sources of high-quality random numbers like *nix /dev/rand and Windows' RNGCryptoServiceProvider module.
It's still not OK to hold payment card data in that way without defense in depth and PCI data security certification.
Edit: Some encryption schemes handle this salting as part of their normal functioning.

Using asymmetric encryption to secure passwords

Due to our customer's demands, user passwords must be kept in some "readable" form in order to allow accounts to be converted at a later date. Unfortunately, just saving hash values and comparing them on authentication is not an option here. Storing plain passwords in the database is not an option either of course, but using an encryption scheme like AES might be one. But in that case, the key to decrypt passwords would have to be stored on the system handling authentication and I'm not quite comfortable with that.
Hoping to get "best of both worlds", my implementation is now using RSA asymmetric encryption to secure the passwords. Passwords are salted and encrypted using the public key. I disabled any additional, internal salting or padding mechanisms. The encrypted password will be the same every time, just like a MD5 or SHA1 hashed password would be. This way, the authentication system needs the public key, only. The private key is not required.
The private key is printed out, sealed and stored offline in the company's safe right after it is created. But when the accounts need to be converted later, it will allow access to the passwords.
Before we deploy this solution, I'd like to hear your opinion on this scheme. Any flaws in design? Any serious drawbacks compared to the symmetric encryption? Anything else we are missing?
Thank you very much in advance!
--
Update:
In response to Jack's arguments below, I'd like to add the relevant implementation details for our RSA-based "hashing" function:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher rsa = Cipher.getInstance("RSA/None/NoPadding");
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cryptRaw = rsa.doFinal(saltedPassword.getBytes());
Having quickly skimmed over the paper mentioned by Jack, I think I somewhat understand the importance of preprocessing such as OAEP. Would it be alright to extend my original question and ask if there is a way to apply the needed preprocessing and still have the function return the same output every time for each input, just as a regular hashing function would? I would accept an answer to that "bonus question" here. (Or should I make that a seperate question on SOF?)
--
Update 2:
I'm having a hard time accepting one of the present answers because I feel that none really does answer my question. But I no longer expect any more answers to come, so I'll accept the one that I feel is most constructive.
I'm adding this as another answer because instead of answering the question asked (as I did in the first response) this is a workaround / alternative suggestion.
Simply put:
Use hashes BUT, whenever a user changes their password, also use your public key as follows:
Generate a random symmetric key and use it to encrypt the timestamp, user identifier, and new password.
The timestamp is to ensure you don't mess up later when trying to find the current / most up-to-date password.
Username so that you know which account you're dealing with.
Password because it is a requirement.
Store the encrypted text.
Encrypt the symmetric key using your public key.
Store the public key encrypted symmetric key with the encrypted text.
Destroy the in-memory plaintext symmetric key, leaving only the public key encrypted key.
When you need to 'convert' the accounts using the current password, you use the private key and go through the password change records. For each one:
Using the private key, decrypt the symmetric key.
Using the symmetric key, decrypt the record.
If you have a record for this user already, compare timestamps, and keep the password that is most recent (discarding the older).
Lather, rinse, repeat.
(Frankly I'm probably overdoing things by encrypting the timestamp and not leaving it plaintext, but I'm paranoid and I have a thing for timestamps. Don't get me started.)
Since you only use the public key when changing passwords, speed isn't critical. Also, you don't have to keep the records / files / data where the plaintext password is encrypted on the server the user uses for authentication. This data can be archived or otherwise moved off regularly, as they aren't required for normal operations (that's what the hash is for).
There is not enough information in the question to give any reasonable answer. Anyway since you disable padding there is a good chance that one of the attacks described in the paper
"Why Textbook ElGamal and RSA Encryption are Insecure" by
D. Boneh, A. Joux, and P. Nguyen is applicable.
That is just a wild guess of course. Your proposal could be susceptible to a number of other attacks.
In terms of answering your specific question, my main concern would have been management of the private key but given it's well and truly not accessible via any computer system breach, you're pretty well covered on that front.
I'd still question the logic of not using hashes though - this sounds like a classic YAGNI. A hashing process is deterministic so even if you decided to migrate systems in the future, so long as you can still use the same algorithm, you'll get the same result. Personally, I'd pick a strong hash algorithm, use a cryptographically strong, unique salt on each account and be done with it.
It seems safe enough in terms of what is online but have you given full consideration to the offline storage. How easy will it be for people within your company to get access to the private key? How would you know if someone within your company had accessed the private key? How easy would it be for the private key to be destroyed (e.g. is the safe fireproof/waterproof, will the printed key become illegible over time etc).
You need to look at things such as split knowledge, dual control, tamper evident envelopes etc. As a minimum I think you need to print out two strings of data which when or'd together create the private key and then have one in your office and one in your customers office,
One serious drawback I've not seen mentioned is the speed.
Symmetric encryption is generally much much faster than asymmetric. That's normally fine because most people account for that in their designs (SSL, for example, only uses asymmetric encryption to share the symmetric key and checking certificates). You're going to be doing asymmetric (slow) for every login, instead of cryptographic hashing (quite fast) or symmetric encryption (pretty snappy). I don't know that it will impact performance, but it could.
As a point of comparison: on my machine an AES symmetric stream cipher encryption (aes-128 cbc) yields up to 188255kB/s. That's a lot of passwords. On the same machine, the peak performance for signatures per second (probably the closest approximation to your intended operation) using DSA with a 512 bit key (no longer used to sign SSL keys) is 8916.2 operations per second. That difference is (roughly) a factor of a thousand assuming the signatures were using MD5 sized checksums. Three orders of magnitude.
This direct comparison is probably not applicable directly to your situation, but my intention was to give you an idea of the comparative algorithmic complexity.
If you have cryptographic algorithms you would prefer to use or compare and you'd like to benchmark them on your system, I suggest the 'openssl speed' command for systems that have openssl builds.
You can also probably mitigate this concern with dedicated hardware designed to accelerate public key cryptographic operations.

Authenticating addons and files

If you ever played the original startcraft and selected an official map made by Blizzard you would notice a little "Blizz" icon next to the map to let you know that it was official and not made by third-party.
I wish to implement a similar system in my application whereby addons and files can be authenticated to let the user know whether or not they came from me or somebody else.
I know very little about security and would appreciate any help in this matter.
Public key cryptography. The client application has a copy of the official author's public signing key, and verifies a signature applied to the addon/file made with the author's private key.
Mac's answer is absolutely correct. To be more specific, the process generally would go as follows:
Signing:
A hash (e.g. SHA-1) is created from the content.
The hash is then signed using the private key, resulting in a signature (e.g. using DSA or RSA algorithm).
The signature is included with the content. If the content changes, the signature will become invalid.
Verification:
Client calculates a hash from the content.
The signature is decrypted with the known public key of the author (i.e. you).
If the hash inside the signature matches the calculated hash from #1 then it's OK. Otherwise the content was modified / isn't really from the author (i.e. you).
Some considerations:
You need to use a key size large enough to deter brute forcing.
These algorithms require a source of random data - both when generating keys and when signing, for example. If this is violated, then often the private key can be trivially revealed.
"Encrypting the hash with the public key" is a simplistic explanation. For example, with RSA - the hash needs to be padded with other data. On verification, the padding has to be checked as well. Otherwise, the signatures may be able to be forged easily. (See: OpenSSL debacle from a few years ago).
The standard advice is to use a proven, off-the-shelf cryptography library written by those with more experience. You need to be able to feed the library the key pair, and data to be signed/verify and say "sign/verify this" with minimal code involved. If you're worrying about the details of padding, or anything like that - you're probably doing it wrong. See: System.Security.Cryptography namespace in Microsoft .NET (very easy to use), or Microsoft CryptoAPI if you're doing standard Windows C/C++ programming. Other cross-platform libs exist too: pick something that works well on your platform.

Resources