There is this question on SO:
What is the difference between encrypting and signing in asymmetric encryption?
My question is not a duplicate. I am asking if there is difference between two programmatically.
I have an openssl C++ API to sign and verify a message. Let say two functions:
sign
verify
Let say two sides who interchange messages are A and B.
Currenlty sign function uses A_privateKey, and verify function uses B_publicKey.
Now, I want to encrypt some part of the message.
So, could I do it just using sign function with B_publicKey?
Or the algorithm to encrypt is totally different and I need to implement a new function?
Or with some modification in sign function (removing generating hash, for ex) does it just work?
Now, I want to encrypt some part of the message.
So, could I do it just using sign function with B_publicKey?
The output of the sign function is an encrypted hash of the original message. If "A" were to tranmit the output of sign as you describe, the only thing B could do is decrypt it back to the hash of the original message. He wouldn't have the actual message.
Because assymetric encryption can be a very computationally expensive operation that doesn't scale well for long messages, the standard pattern is this:
Alice generates a message she wants to send to Bob.
Alice generates a symmetric key first
Alice encrypts the message with this symmetric key.
Alice encrypts the symmetric key with Bob's public key
Alice transmits the encrypted message and encrypted key to Bob.
Then Bob does this:
Bob receives both the message that was symmetrically encrypted and
the assymetrically encrypted key.
Bob decrypts the symmetric key with his public key
Bob uses the symmetric key to decrypt the encrypted message
There's probably a ton of other security principals missing as well, but the above is the general idea.
Related
I hope someone can help me to understand how DEK and KEK works in layman term.
This is my understanding so far
Part 1
Uploaded data is stored in chunks. Each chunk is encrypted with DEK. DEK is stored near the chunked data.
Part 2 DEK of the data chunk is wrapped with KEK
Part 3 KEK is stored in KMS.
This sentence from a Google's course material really tripped me.
The wrapped data encryption keys are then stored with this data
My brain goes crazy with these questions:
What is this wrapped data encryption keys? Isn't that the KEK in part 2?
If that's the KEK in part 2, shouldn't that be in KMS?
If yes, does KMS store data?
If no, how many DEKs a chunk of data has? 2 DEKs?
What keys do we(users/customers)keep?
We store the data with which keys?
What is this wrapped data encryption keys? Isn't that the KEK in part 2?
The wrapped DEK is the result of encrypting the DEK with the KEK. The key encryption key is called that because it encrypts (data encryption) keys.
If that's the KEK in part 2, shouldn't that be in KMS?
Does KMS store data?
No. As the name suggests, a key management system only stores keys, and specifically KEKs.
How many DEKs does a chunk of data have? 2 DEKs?
One. Data is encrypted only once, so there is only one key.
What keys do we (users/customers) keep?
Only the KEK. When using a KMS, not even that key is known to you, the user of the KMS.
We store the data with which keys?
With the wrapped DEK.
Here is a concrete example:
Data (i.e. plaintext): yellow submarine
KEK (aka. master key): my-secret-master
DEK (randomly generated for each piece of data): ttlly-random-dek
Ciphertext: Base64(AES(Data, DEK)) = TJ4SLFTy0sMdvGe55QCuYQ==
Wrapped DEK: Base64(AES(DEK, KEK)) = lOEmql1JuSONZ8uLorc/vQ==
The second operation is done by the KMS, if there is one (it has to be, because it's the only one in possession of the KEK, and it will never disclose it).
What you store together: TJ4SLFTy0sMdvGe55QCuYQ== and lOEmql1JuSONZ8uLorc/vQ==.
And to reconstruct the plaintext given TJ4SLFTy0sMdvGe55QCuYQ== + lOEmql1JuSONZ8uLorc/vQ==:
DEK: AES'(Base64'(lOEmql1JuSONZ8uLorc/vQ==), KEK) // = ttlly-random-dek Plaintext: AES'(Base64'(TJ4SLFTy0sMdvGe55QCuYQ==), DEK)
The first operation is done by the KMS if there is one (again, it has to be, because the KEK is involved).
In the example above I conveniently chose 16 bytes of data and 16-byte keys, so I could gloss over block cipher modes and IVs/nonces. In practical applications the IVs for each encryption have to be retained as well, of course.
Note that the KMS never sees your data, and it only has to encrypt and decrypt tiny amounts. That is why we do all of this; only you, the owner of the data ever sees it in plaintext (assuming the KMS is an honest party, obviously).
Don't kill me if I'm about to ask something stupid. But I'm very noobish in this whole crypto world, and I'm terribly fascinated about its technology.
So just for education purposes I've decided to build my own blockchain following more or less the bitcoin principles (ECC keypair generation using the secpbk1 curve, SHA256 as hashing algo, dynamic diff based on the timestamp of the previous block, p2p connectivity etc..). But I've came to a point where I'm pretty confused about the blockchain's wallet itself.
For what I've learned so far, each transaction has to be signed by a wallet. So my transactions has basically three fields: input, outputs and id. Since the user's wallet signs the outputs field of the transaction, this can't be changed anymore without being signed again by the same private key that belongs to the public key contained in the input field, how can I reward the miners?
If I got it right, the miner creates a transaction signed somehow by the chain using the fee in the outputs field, or by asking the chain itself to generate and sign a special reward transaction for that miner.
The guide that I was following was using the second approach, and was generating a blockchain wallet each time the program was executed on a client. This approach left me perplexed:
wouldn't a client generate a new wallet for "his" blockchain each time it goes back online? If so, wouldn't this create a mess on the transactions signed on the chain? Since each miner (therefore peer) signing its own reward would use a different blockchain wallet than the other peers? Wouldn't this lead to any problems?
The first one that I might think of, is that if we generate a new blockchain wallet that signs rewards for miners, each peer would create a different wallet, so wouldn't this lead to many "ghosts" wallets in the chain, that spits out rewards tokens from nowhere? Is this supposed to happen?
For what I think is definitively more straightforward to use the fee amount to reward the miner, but this doesn't solve my doubts at all. Since the outputs of the transactions are signed upon creation, how could the peer initiating the transaction know upfront the possible miner who finds the block? And if he can't know it, how could possibly the miner "extract" its reward without tampering the transaction itself? Of course it could create a new transaction, and add that to the block. But who would sign that transaction? From where those reward tokens come?
And if the answer is not to generate a new wallet each time, where could you possibly store that very first private key of the chain's wallet where no one can see it, but still be able to use it, without having to put a server in the middle?
Which in my opinion breaks the whole decentralized concept and would add a single point of failure.
I've also implemented a transactions pool, that automatically filters out invalid (tampered) transactions, whenever a miner requests a sub set of them to stamp in a block. But does this mean that the miner for that only exception can tamper the transaction since it'll be "forged" in the block? So who gives a *** if it was tampered once it got in the chain? MEEEEEH that doesn't sound nice at all.
I'm terribly confused, and I'm dreaming key pairs at night. Please help me.
wouldn't a client generate a new wallet for "his" blockchain each time it goes back online? If so, wouldn't this create a mess on the transactions signed on the chain? Since each miner (therefore peer) signing its own reward would use a different blockchain wallet than the other peers? Wouldn't this lead to any problems?
You don't say what problems you think this will lead to. I can't think of any.
For what I think is definitively more straightforward to use the fee amount to reward the miner, but this doesn't solve my doubts at all. Since the outputs of the transactions are signed upon creation, how could the peer initiating the transaction know upfront the possible miner who finds the block? And if he can't know it, how could possibly the miner "extract" its reward without tampering the transaction itself?
The simplest solution to this is for the transaction itself to just contain its inputs and outputs. The fee is the difference between the total inputs and the total outputs.
The miner just includes the transaction in the block of transactions they mine. They also add one additional transaction into the block, sending themselves the reward. Obviously, they know their own destination address. Every participant who receives the newly-mined block checks to make sure this transaction is valid (just as they check every other one) and doesn't claim a larger reward than is allowed.
And if the answer is not to generate a new wallet each time, where could you possibly store that very first private key of the chain's wallet where no one can see it, but still be able to use it, without having to put a server in the middle?
Typically in a file on the local disk. The private key isn't really needed anyway -- you only need it to send. You don't need it to mine or report. So it can be prompted for or decrypted only when actually needed.
Of course it could create a new transaction, and add that to the block. But who would sign that transaction? From where those reward tokens come?
The usual rule is that the reward transaction has no inputs, one output, and no signature. The tokens come from the pool of unclaimed miner reward tokens which can be finite or infinite depending on the blockchain's design. (For bitcoin, this pool is finite.)
I am trying to use the low level message functions to create a CAdES-BES compliant signature.
The signature has to be in proper PKCS#7 format along with four signed attributes present.
The first two, type and hash are automatically put but the crypto library.
The third one is the time of the message. I was able to put this using CryptEncodeObject and szOID_RSA_signingTime
"1.2.840.113549.1.9.5".
The fourth one is the signing certificate, which OID's is not supported by the crypto API, 1.2.840.113549.1.9.16.2.47.
To be able to add this manually I have to know how CryptEncodeObject works internally, and the sort of structure to encode:
SigningCertificateV2 ::= SEQUENCE {
certs SEQUENCE OF ESSCertIDv2,
policies SEQUENCE OF PolicyInformation OPTIONAL
}
ESSCertIDv2 ::= SEQUENCE {
hashAlgorithm AlgorithmIdentifier
DEFAULT {algorithm id-sha256},
certHash Hash,
issuerSerial IssuerSerial OPTIONAL
}
Hash ::= OCTET STRING
IssuerSerial ::= SEQUENCE {
issuer GeneralNames,
serialNumber CertificateSerialNumber
}
And more structures that have to be included before it's completed.
I could try to use an ASN.1 compiler to build the whole thing, then a DER encoder to encode it, but is there a simpler way?
I did it, you have to use an ASN.1 compiler and then encode signed attributes with the CMS.
https://www.codeproject.com/Articles/1256991/AdES-An-implementation-of-CAdES-for-Windows-in-Cpl
I'm having trouble encrypting data with node and decrypting with RNCryptor. My understanding is that RNCryptor uses a special data format?
The cryptotext is being generated as follows:
var crypto = require('crypto');
var cipher = crypto.createCipher('aes-256-cbc','InmbuvP6Z8');
var text = "123|123123123123123";
var crypted = cipher.update(text,'utf8','base64');
crypted += cipher.final('base64');
And I'm decrypting like this:
[RNDecryptor decryptData:plainText withPassword:password error:&error];
How am I supposed to do this? When I try to decrypt currently I get an empty NSData and no error.
Yes, RNCryptor outputs encrypted data in its own format. If you build this format in your own encryption code (and use the same encryption params), you can pass it to JNCryptor to decrypt.
For RNCryptor format version 3, the first 34 bytes are as follows:
byte[0] is the version (3).
byte[1] defines whether a password or a key is used (1 for password, 0 for key).
bytes[2-9] carry the encryption salt.
bytes[10-17] carry the HMAC salt.
bytes[18-33] carry the IV.
Then comes the encrypted ciphertext.
Then the last 32 bytes hold the (SHA256) HMAC for the ciphertext.
The spec is here: https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md
RNCryptor is more than just encryption, it is an entire secure "stack" including authentication, password key derivation, versioning and random iv. Since your encryption is just the encryption portion it will be incompatible.
Either use RNCryptor for the encryption or change to a simple decryption method. Since the question has a commoncrypto tag and the encryption code look like it might be Swift (there is no language tag) just consider using Common Crypto in Objective-C for the decryption. See the SO answer for example code.
I just want to know the exact formula (or algorithm) used for generating the pseudo random values used in encrypting the zip file. I am trying to create a password hacker(for zip files) and I also require to know how to verify if the random password generated by my program is correct. I have tried searching for an answer to this in Google but I could't find a direct solution.
I am trying to program this zip hacker in c++.
note: by formula (or algorithm) I meant: key derivation function.
I just want the necessary information as quick as possible, that's why I posted it here!
Different versions of zip-files do it differently, but basically you have an encryption-header specifying what encryption is used according to the zip-file specification.
For example, the strong encryption header looks like below and specifies the encryption algorithm in the AlgID-field.
4.5.12 -Strong Encryption Header (0x0017):
Value Size Description
----- ---- -----------
0x0017 2 bytes Tag for this "extra" block type
TSize 2 bytes Size of data that follows
Format 2 bytes Format definition for this record
AlgID 2 bytes Encryption algorithm identifier
Bitlen 2 bytes Bit length of encryption key
Flags 2 bytes Processing flags
CertData TSize-8 Certificate decryption extra field data
(refer to the explanation for CertData
in the section describing the
Certificate Processing Method under
the Strong Encryption Specification)
7-zip uses AES-256 encrpytion for 7z/zip archives.(see here)
7-Zip also supports encryption with AES-256 algorithm. This algorithm uses cipher key with length of 256 bits. To create that key 7-Zip uses derivation function based on SHA-256 hash algorithm. A key derivation function produces a derived key from text password defined by user. For increasing the cost of exhaustive search for passwords 7-Zip uses big number of iterations to produce cipher key from text password.
Also, keep in mind that Brute force attacks are a waste of time. I won't go into details why, I will instead direct you to Jeff Atwood's blog, he has an excellent post.