Swift: RSA Encrypt a string with a specific private key - swift

I need to write a method in Swift which uses a particular PRIVATE KEY to encrypt a timestamp using RSA. This is NOT used for authentication (rather it validates the client app to the server), I know that you would normally encrypt with a public key to ensure security.
I have a key:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDIg+wteSjhalc1hSHEiUnz9X1pkrObCjaXMHqeSdfFQ/h5Q1Uh
...
o7wjoqFNxFnQMAYvkLzQZ7Y2jjfSJkaTVnhzJIZOfQ0=
-----END RSA PRIVATE KEY-----
And I need to encrypt a string using this particular key. I have written the Android application version of this app, but if I need to re-generate the keys specifically for iOS it's not a problem, but I would need this file for the Android version as well.
I have looked at the following web sites:
http://jslim.net/blog/2013/01/05/rsa-encryption-in-ios-and-decrypt-it-using-php/ Seems useful but it insists that the key be in a .der format - plus it's in Objective-C. Is it possible to generate a Key pair in both DER and PEM format, or convert between the two (using something like https://www.sslshopper.com/ssl-converter.html)?
https://github.com/henrinormak/Heimdall - but you cannot import a custom private key
https://github.com/ideawu/Objective-C-RSA/blob/master/RSA.m - seems long winded and is also in objective-c
One requirement is that all apps use the SAME key - it cannot be generated by each installation of the app. Also my Android app must be able to use the key as well (I am open to rethinking the Android version as leaving the key as a RAW file is not preferred for me).
Any help will be appreciated.
Other references checked:
How to encrypt a string with private key and decrypt with public key?
Using RSA public key to encrypt a string

Related

Convert between X.509 and PKCS#1 RSA Public keys

I am using CryptoPP to generate RSA keys, and run encryption / decryption of large amounts of data. Because of this, I am deciding to input data through a web socket from a phone app (currently using flutter), along with already in place desktop clients (the desktop clients work as they support the format the server uses).
My issue is that the keys are in different formats, everything I try (specifically simple_rsa) fails to be compatible with the server. As flutter only supports PKCS#1 as far as I am aware.
I understand now that the public key is formatted with X.509 from crypto++ wiki, and through use of an online tool this I have found that the cipher type (I'm guessing padding?) is OAEP with SHA-1.
These show that both key types are encoded with ASN.1
For reference, the server code is very similar to this, but uses a key size of 4096
////////////////////////////////////////////////
// Generate keys
AutoSeededRandomPool rng;
InvertibleRSAFunction parameters;
parameters.GenerateRandomWithKeySize( rng, 1536 );
RSA::PrivateKey privateKey( parameters );
RSA::PublicKey publicKey( parameters );
And the key is written to a .pem file by encoding the data in base64.
std::string base64 = macaron::Base64::Encode(pubKeyString);
std::string base64LineLength;
int i = 0;
while (i < base64.size()) {
if (i % 64 == 0 && i)
base64LineLength.push_back('\n');
base64LineLength.push_back(base64[i]);
i++;
}
base64LineLength = "-----BEGIN PUBLIC KEY-----\n" + base64LineLength + "\n-----END PUBLIC KEY-----\n";
std::ofstream pubkeyOut("secure_chat_rsa.pub");
pubkeyOut << base64LineLength;
pubkeyOut.close();
Also, this is an example of a public key with the formatting (X.509)
-----BEGIN PUBLIC KEY-----
MIICIDANBgkqhkiG9w0BAQEFAAOCAg0AMIICCAKCAgEAmQlXbYS1I+B4AUXwU/ua
KgwdrUzYRwXPaR6435DAguDGW+zTeekDgP55lg9Lqn32UW+T/5PIgYQ2HpA/gfYU
IMvrLAhSSaXSEFzIzdwgFgo3IMZHdhcx/xP/+pmDTrflhmba/7QEOE/bC2hFzQCh
2Zd1DJbItIR64uyyi1Z0B6bFlLyDA2E+lctBLhuHSyYSqPrVUqYTRdptLNk8/vsN
HdWKrYq7H8n4QKQefspD5zU3SJdUumOIusqzXeMe70mPds+Qe9u4Ti5Ca7guZCN4
kNXUF/kJH7Y3dBh7409r2v/bjGEznFpY1cmP1f0EFYTQU1BirbNiwqnAjhy9fT2M
quSlpmwo7V0YbZDI/KBcLDxTY64oO6XMz6DHkdmpOluALWQAJZFJ7iHntsLp1GRB
DtLaidCr9EI+pN7cfwsSYLRHtEmUZoiz30RZra5c5+aE4sg24c/PJ5nVe9GDOaQs
dHL3+sc2r9LTEK9pCSO5cWdbxSRvKNrevElr2+8ORUQL1cRsCmL8ri4eYwrwukBn
HFJc1pZFD8i5sFjnJxEIKzoIa+eGVgqEwkwxKvNuUUyH3tJD9YJVlhs1G68VlxOf
RSk+LZGhwSMZs+PbfuxmPQZyapT5TqRJ2JJ7f9HErIq5f8WjBrzcqy63rygy33Hw
M94iQLwuTM3X99Z4FnyTsTECARE=
-----END PUBLIC KEY-----
Edit:
I have tried putting the key through an ANS.1 decoder, and extracted the bit string from it, then put that through a base64 encoder to give:
MIICCAKCAgEAmQlXbYS1I+B4AUXwU/uaKgwdrUzYRwXPaR6435DAguDGW+zTeekDgP55lg9Lqn32UW+T/5PIgYQ2HpA/gfYUIMvrLAhSSaXSEFzIzdwgFgo3IMZHdhcx/xP/+pmDTrflhmba/7QEOE/bC2hFzQCh2Zd1DJbItIR64uyyi1Z0B6bFlLyDA2E+lctBLhuHSyYSqPrVUqYTRdptLNk8/vsNHdWKrYq7H8n4QKQefspD5zU3SJdUumOIusqzXeMe70mPds+Qe9u4Ti5Ca7guZCN4kNXUF/kJH7Y3dBh7409r2v/bjGEznFpY1cmP1f0EFYTQU1BirbNiwqnAjhy9fT2MquSlpmwo7V0YbZDI/KBcLDxTY64oO6XMz6DHkdmpOluALWQAJZFJ7iHntsLp1GRBDtLaidCr9EI+pN7cfwsSYLRHtEmUZoiz30RZra5c5+aE4sg24c/PJ5nVe9GDOaQsdHL3+sc2r9LTEK9pCSO5cWdbxSRvKNrevElr2+8ORUQL1cRsCmL8ri4eYwrwukBnHFJc1pZFD8i5sFjnJxEIKzoIa+eGVgqEwkwxKvNuUUyH3tJD9YJVlhs1G68VlxOfRSk+LZGhwSMZs+PbfuxmPQZyapT5TqRJ2JJ7f9HErIq5f8WjBrzcqy63rygy33HwM94iQLwuTM3X99Z4FnyTsTECARE=
However, this is not a valid RSA key. (from trying to encrypt with it)
I have 4 main questions:
Is there a way for the X.509 format to be converted to PKCS#1 and vice versa
If converted, will the output be compatible. When the server encodes data, will the client be able to decrypt it if the keys are converted?
Is there a way for flutter to work with X.509 formatted keys?
If this is only due to ANS.1, how exactly would you go about encoding ciphers or keys?

I wanted to decrypt a message using RSA Public Key in Swift

I am new to Swift Language . I wanted a swift code for decrypting a message using RSA Public key.
Padding used is "PKCS1". (I am not talking about Signature , I want the code for decryption of message itself using Public Key) .
Thanks in Advance
I wanted a swift code for decrypting a message using RSA Public key.
What you are asking for is not possible.
With RSA public keys are used to encrypt messages, while the private key is used to decrypt encrypted messages. It's the other way around with signatures, and probably the reason why you are confused. Signatures are created using the private key and can be verified by public keys.

Digital identity is equal to public key + private key?

I am reading about application code signing in iOS and I don't understand why both private and public key is together? What is the public key and certificate used for when you are signing the application with the private?
Xcode uses your digital identity to sign your application during the
build process. This digital identity consists of a public-private key
pair and a certificate. The private key is used by cryptographic
functions to generate the signature. The certificate is issued by
Apple; it contains the public key and identifies you as the owner of
the key pair.
Let's sum up the process:
You encrypt an hashed digest (like md5 or sha-1) of the executable of application with your private key. That's "signing".
Your users decrypt it with your public key (they have it because it's public) and check it against the executable. As long as your private key stays private, it's you who "signed" it. That's called "verifying".
What about the digital identity then:
You public key isn't public by itself, it must be somehow shared, "made public", and signed by the Certification Autority (hereby CA) too, (that's the CA encrypting it —or an hash of it— with their, one of their, magical mysterious private keys) this guarantees the sharing process hasn't been tampered with by a man in the middle.
So, public key and certificate (CA signature — CA encrypting your public key) identify you (as such are considered part of your "digital identity") and must reach the end user somehow (via a third party, embedded into the executable, you name the way)
The public key is needed so anyone can decrypt the application, and is hence included in the build.

RSA iphone public key

I have a Public Key generated in JAVA.
I want to use this key and crypt the data using RSA and send it to the server.
How can I do that using the iPhone SDK?
Thanks
Unfortunately, iOS has no public APIs to deal with raw RSA keys.
There are two things you can do:
1) Instead of giving your app a Public Key, give your app a certificate instead. You can import the certificate with SecCertificateCreateWithData. Then create a trust with SecTrustCreateWithCertificates. Once you have the trust, you can extract the public key with SecTrustCopyPublicKey.
2) The other option is to include OpenSSL in your project. It has all the APIs you need, you can google for example code on how to work with RSA keys. This might be the simpler solution.
I have made available a script to easily build OpenSSL from source. You can grab it from:
http://github.com/st3fan/ios-openssl
If your public key is in modulus/exponent form, this question may help: Convert XML Dsig format to DER ASN.1 public key
I figured out how to binary-encode the modulus and exponent into the DER ASN.1 format that the SecKeyWrapper class of Apple's CryptoExercise project uses to import an external key.

why do we need the pfx (key exchange) file?

If we make the private key exportable (using -pe option in makecert), then in theory we have both an exportable private key and the public key (public key in certificate) -- which can be transferred or imported to another machine.
So, my question is, why do we still need to create the .pfx file (key exchange file, which contains private and public keys) -- making the private key exportable in certificate could do anything we want? Any scenarios pfx file could cover which making private key exportable in certificate could not achieve?
thanks in advance,
George
Is there a makecert command line you have found that will generate a certificate file that includes a private key? I never have. I have seen someone allude to the fact that there is a version of makecert that can produce .pfx files but also have never seen that.
That means at the very best you can create TWO files with makecert if you want a private key file. One for the certificate and one for the private key. You can copy both those files to another computer and import them using makecert.
The advantage of the .pfx certificate format is that you can combine the two files with the certificate and private key into one. This is more convenient and also means you can use the file with the .Net X509Certificate2 class for use with an SslStream.
Your pfx file can be password protected, that would add a layer of protection
The problem is, the X509 Certificate standard (the certificate) does not include the private key. The certificate contains the subject public key info (aka, the public key) and information about the holder of the private key, but the standard does not support including the private key. This is the basic idea of PKI - the certificate is the public info you share with the world, the private key is something you hold very securely.
Making a private key exportable in any mechanism (for example, makecert), means you are telling that product that the key can be exported. It doesn't specify the file format that you would use to store it. A pfx file is one way of storing the private key - it uses the PKCS 12 standard. Java Key Stores (*.jks) are another way to do the same thing. Most commerically supported standards have similar common features - they protect the private key by encrypting it. The encryption can be unlocked using a password. They couple the private key with the certificate that decribes it.
If you want to build a PFX file, you should have both x509 cert public key and private key file which you can generate using makecert command. PFX can be generated using PVk2PFX command which you can find Microsoft SDK installation directiory.