Convert java.security.PublicKey into bouncy castle PGPPublicKey - cryptography

I am trying to encrypt a string using bouncy castle. The library I am using to retrieve the public key for the encryption returns it as a java.security.PublicKey object. How do I convert it into a PGPPublicKey object so that I can use it to encrypt the file.

You can convert the key using Bouncy Castle JcaPGPKeyConverter.getPGPPublicKey(int algorithm, PublicKey pubKey, Date time)
Note: the time passed in affects the value of the key's keyID, so you probably only want to do this once for a JCA key, or make sure you keep track of the time you used.
See https://borelly.net/cb/docs/javaBC-1.4.8/pg/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.html

Related

Changing a Private Ethereum Key into a PEM or HMAC algorithm in NodeJS

I have a private key, which is:
0x66228b427f07b168c7cb1380aa5554403b9e24bf935a9364c89711a306a23ddb
NOTE: The Original Key was the Public Key when the question was posted:
0x6a2043113D5640F9F50dC593D0DcD8CC1c970EB1
I generated it randomly for this question, so don't worry that it's public on the Internet.
I want to use it as the encryption scheme for a JWT token, using the ES256 algorithm.
To get it into my library, I have to have it in one these formats.
secretOrPrivateKey is a string, buffer, or object containing either the secret for HMAC algorithms or the PEM encoded private key for RSA and ECDSA. In case of a private key with passphrase an object { key, passphrase } can be used (based on crypto documentation), in this case be sure you pass the algorithm option.
Is there any easy way to move the hex value to one of these formats? Or, will this not work because I'm not understanding the difference between an Ethereum Private key and a ES256?
Etherium keys are actually ES256K and not ES256 so in this case it might not be possible.
If you need to turn the key in PEM in NodeJS there is a library called key-encoder for this specific purpose. Which can be accomplished with the following code.
var KeyEncoder = require('key-encoder');
console.log(KeyEncoder.default);
let keyEncoder = new KeyEncoder.default('secp256k1')
var pemPrivateKey = keyEncoder.encodePrivate('0x66228b427f07b168c7cb1380aa5554403b9e24bf935a9364c89711a306a23ddb', 'raw', 'pem')
console.log(pemPrivateKey);

Need to change encryption algorithm to AES-256

I wrote a test program to read a users cert from the cert store, and encrypt some text. However, I realize that the encryption algorithm used is 3DES. I need to change this to AES-256. I read a similar post on here, but for me, i think my situation is slightly different...So, I'll get straight to the point.
Using the suggested method:
var recipient = new CmsRecipient("MyCert.cer");
recipient.EncryptionAlgorithms = new EncryptionAlgorithm[] {
EncryptionAlgorithm.Aes256
};
var CmsCollection = new CmsRecipientCollection();
CmsCollection.Add(recipient);
// Followed by calling ApplicationPkcs7Mime.Encrypt(CmsCollection, p7m);
I'm able to change the encryption algorithm... However my key-encryption algorithm, is not the same if I were to do it using my original method of simply using the MailboxAddress to encrypt. E.g.:
MimeMessage mm = new MimeMessage();
mm.From.Add(new MailboxAddress(from));
mm.To.Add(new MailboxAddress(to));
ApplicationPkcs7Mime.Encrypt(mm.To.Mailboxes, p7m);
Using the CmsRecipientCollection method, this is the result of my pkcs7m file:
You can see, that the key-encryption algorithm has changed to rsaOAEP,and the email client that I'm sending this message to cannot recognize this algorithm.
Whereas, using the Mailbox method to encrypt:
I'm stuck with 3DES, while the key encryption algorithm is correct...
So I guess, end of day, what I'm asking is, is there a way to get both key-encryption algorithm to be rsaEncryption, and the block cipher to be AES-256?
I saw an method UpdateSecureMimeCapabilities in the API reference, would this be able to do the job?
Also, I guess a more fundamental question is, why would the key-encryption algorithm change if both methods are essentially using the same cert?
Thanks!
Update:
So I created a custom class to override the GetPreferredEncryptionAlgorithm function, however it's still falling back to 3DES.
public class CustomWindowsSecureMimeContext : WindowsSecureMimeContext
{
public CustomWindowsSecureMimeContext () : base ()
{
}
protected override EncryptionAlgorithm GetPreferredEncryptionAlgorithm(CmsRecipientCollection recipients)
{
return EncryptionAlgorithm.Aes256;
}
}
Did I override it correctly?
The UpdateSecureMimeCapabilities method isn't going to help in your case. It's not used when enveloping data, it's only used when decoding signed messages (it's a way for you to update your database of S/MIME capabilities of the email clients used by your correspondents).
There is no way to specify a key encryption algorithm in MimeKit because I haven't been able to figure out how to specify it in BouncyCastle (used by any of the BouncyCastleSecureMimeContext subclasses) nor in Microsoft's CMS API (used by WindowsSecureMimeContext). It seems to make that decision on its own.
Whichever SecureMimeContext class you use, you can override the GetPreferredEncryptionAlgorithm() method(s) to provide your own algorithm for choosing an encryption algorithm that would be suitable to use to encrypt the message to all of the specified recipients -or- you could override the GetCmsRecipient() method which takes a MailboxAddress and creates a new CmsRecipient for that recipient.
The other option is to use the MimeKit.Cryptography.CmsRecipient[Collection] API's in order to set the CmsRecipient.EncryptionAlgorithms property which represents the encryption algorithms supported by that recipient's email client. If you set an array of EncryptionAlgorithms that includes Aes256 for each recipient, then that algorithm will be chosen.

send public key to host app in java card

I am new to java card applet development.i want to create application which send me to public key for the future authentication.for the movement i used RSA algorithm for the create public key and private key.
keys = new KeyPair(KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_2048);
keys.genKeyPair();
rsa_publicKey = (RSAPublicKey) keys.getPublic();
now i want to send the public key to my host application.i found some way using modulus and exponent send the public key to host application.but i don't know how to implement that one.can some one please help me to implement the send public key to host application..
Thanks
SSV
If you already have the RSAPublicKey instance it is easy. There you have to methods for getting the modulus and the exponent. Both get-methods copy the requested value into a byte array you can return in an result APDU.
Note that for a common JavaCard without extended length APDUs a 2048 bit RSA key is to large to return it in one response APDU. Depending on the available bytes in the response APDU you may even have to split modulus and exponent into 2 or more parts for returning them to the host.

Naming issue of public and private key

I heard that you can use a private key to encrypt data as a method for digital signing. In other words you can encrypt a message with your private key.
In the text they always seem to say only the public key can encrypt and the private key can decipher the text.
I'm assuming this is a bad choice of words. Is it true that a single instance of a key can do only one or the other, but which key is public or private is not a matter of it's function, but of it's distribution or lack thereof.
For a beginner, the terminology is confusing. RSA can be used for 2 distinct crypto functions: data encryption and digital signatures.
For data encryption, you encrypt data using the recipient's public key; they decrypt it using their private key. Note that due to various limitations of RSA, the "data" that is encrypted and decrypted is usually just a key for a symmetric algorithm.
For digital signatures, you sign the data using your private key; they verify the signature over the data using your public key. Again, various limitations of RSA mean that what is actually operated on by the RSA algorithm is normally a secure hash of the data.
Sometimes the signing operation is called "encrypting with the private key", and the verifying operation is called "decrypting with the public key". I think this just confuses people so I always prefer the terms signing and verifying in this context. Furthermore, "encrypt" and "decrypt" make no sense for other signature algorithms like DSA and ECDSA.
You CAN generate public key from private key.
You CAN'T generate private key from public key (well, you might can, but this is extremely computationally expensive).
That is the difference between the two. They are NOT interchangeable (so, for instance, you SHOULD NOT publish your private key, and keep public key to yourself) because of the way how the algorithms works.
Take for instance RSA. The algorithm base is the problem of integer factorization. You choose two big integers p and q and multiply them to get n = p*q. Then you create public and private key:
Public key: (n, e)
Private key: (p, q, d)
Then:
It is easy to calculate public key from private key:
n = p*q
e = d^(-1) mod φ(n), where φ(n) = (p-1)(q-1)
It is hard to calculate private key from public key - it requires factorization of n to get p and q, which is extremely hard if p and q are big enough.
You release your encryption key to the public, and keep your decryption key private. That way anyone can send you encrypted data that only you can decrypt.
If you did it the other way around, then you would be the only one able to encrypt your data, but anyone could decrpyt it. That makes no sense. If everyone can decrypt your message you might as well send it unencrypted. There is no point encrypted a message and then making the decryption key public.
There are two types encryption one is symmetric another one is asymmetric .In symmetric the key used to encrypt and decrypt is the same . in asymmetric the key used to encrypt is public key and decrypt is private key ..
all works on the principle of a secrecy of the key .In Digital signing commonly used as a part of SSL / TLS protocols uses the asymmetric encryption for the authentication and sharing of the master key which is used further for encrypting the communication line.

I'm using Wincrypt for Diffie-Hellman-- can I export the shared secret in plain text?

OK-- thanks to Mike, I was able to get Wincrypt to generate a Diffie-Hellman keypair. I figured out out to export the public key, and how to import the other party's public key. According to the docs, upon import of the other party's public key, the shared secret has been computed. Great.
I now need to get ahold of that shared secret, but I don't think its possible. Simply calling CryptExportKey with a type of PLAINTEXTKEYBLOB fails unless I call CryptSetKeyParam to change the algorithm id from CALG_AGREEDKEY_ANY to something... else. But I don't want something else, I want the shared secret. The API, however, seems designed to discourage this.
Any ideas out there? I should note that the problem here is that I'm only writing one side of an implementation of WiFi Protected Setup. So the protocol is defined for me, and the other party is not giving me HCRYPTKEYs.
This looks like what you need...
from: http://msdn.microsoft.com/en-us/library/aa381969(VS.85).aspx
To import a Diffie-Hellman public key and calculate the secret session key
Call the CryptAcquireContext function to get a handle to the Microsoft Diffie-Hellman Cryptographic Provider.
Create a Diffie-Hellman key by calling the CryptGenKey function to create a new key, or by calling the CryptGetUserKey function to retrieve an existing key.
To import the Diffie-Hellman public key into the CSP, call the CryptImportKey function, passing a pointer to the public key BLOB in the pbData parameter, the length of the BLOB in the dwDataLen parameter, and the handle to the Diffie-Hellman key in the hPubKey parameter. This causes the calculation, (Y^X) mod P, to be performed, thus creating the shared, secret key and completing the key exchange. This function call returns a handle to the new, secret, session key in the hKey parameter.
At this point, the imported Diffie-Hellman is of type CALG_AGREEDKEY_ANY. Before the key can be used, it must be converted into a session key type. This is accomplished by calling the CryptSetKeyParam function with dwParam set to KP_ALGID and with pbData set to a pointer to a ALG_ID value that represents a session key, such as CALG_RC4. The key must be converted before using the shared key in the CryptEncrypt or CryptDecrypt function. Calls made to either of these functions prior to converting the key type will fail.
The secret session key is now ready to be used for encryption or decryption.
When the key is no longer needed, destroy the key handle by calling the CryptDestroyKey function.