Encryption with Azure Key Vault CryptographyClient - where is encrypt/decrypt happenning? my backend or Azure server side - azure-keyvault

I'm currently using Azure Key vault .net SDK to encrypt/decrypt some data. Azure SDK for .net has a build-in Class called "CryptographyClient" and it has built-in method for doing that:
CryptographyClient.decrypt and CryptographyClient.encrypt
The key I'm using is a RSA key and algorithm I use is RsaOaep, so I assume it is asymmetric encryption. I followed this article to write my c# code. Basically, I get the public part of the asymmetric key from the key vault first, then use it to create a CryptographyClient.
Usually, for asymmetric encryption, we gonna use the public key to encrypt while the private key is for decryption only. So basically, the private key will never leave the Azure Key Vault (always at the Azure server, is it true?).
Now my question is:
when I call CryptographyClient.encrypt, is it only running on the client-side (my local server)? or will it send my plaintext to Azure server and send back the encrypted text?
when I call CryptographyClient.decrypt, since the private key should never leave Azure and you can only decrypt with private key, is it only running on the Azure server-side? Mean that my local server will need to send the encrypted text to Azure and wait for decryption?
I got a feeling that both of those methods are only happening on the client-side and this is what I want. But then it doesn't make sense for decryption.
Thanks for the clarification as I can't find any MS documentation for this.

Operations that use the public key - if they can download the public get i.e., caller has the "get" permission - will happen on the client. They public key is download and operation performed. If the caller doesn't have the "get" permission on that key, the operation will be performed on the service.
These operations include:
encrypt
verify
wrap
Operations that require the private key will always be performed on the service, unless you created a CryptographyClient from your own JSON web key (JWK) that has both the public and private keys.
These operations include:
*decrypt
*sign
*unwrap

All of the encryption/decryption occurs on the server side since that’s where the private key lives.
The CryptographyClient API is based on REST :
https://learn.microsoft.com/en-us/rest/api/keyvault/keys/encrypt
https://learn.microsoft.com/en-us/rest/api/keyvault/keys/decrypt/decrypt
You can run a Fiddler trace while executing your code to see the server communication.

Related

Keycloak - Retrieve RSA public key

I have an app deployed with docker, one of the microservices is a jboss/keycloak server. Everything works fine, but keycloak RSA public key need to be retrieved manually. Is it possible to retrieve RSA public key through REST API?
The url https://<keycloak-server>/auth/realms/<realm> contains a json response with the public key. This isn't advertised so it may change or go away. Using https://<keycloak-server>/auth/realms/<realm>/protocol/openid-connect/certs and setting up something to monitor the jwks response would be a much more maintainable way of handling it.
Since version 14 or so, this is now https://<keycloak-server>/realms/<realm>, i.e., no /auth in the path anymore.
Just for lazy people, as mentioned by #davidav.
It means you get the regular openid-connect keys via
https://<keycloakserver>/realms/<realm>/protocol/openid-connect/certs

View plain response (from HTTPS) in WireShark

I couldn't find exact answer.
In similar topics, people say that without Private key you can't view HTTPS response, but I am surprised, why key needed at all? For example, when browser requests https://example.com, it can read view it's html output.
And I want the same in WireShark (one of my program reads response from https://example.com and want to view just that page's outputed HTML). However, I can't understand why Private key is needed with this simple task?
If you didn't need to know the private key, an attacker wouldn't need it either – then any HTTPS traffic including login information, credit card numbers, photos, etc could be read by anybody that is on the same network as you (somebody listening to wi-fi traffic), or anywhere between you and the server (ISPs). This would be a disaster.
HTTPS (or more specifically TLS) was created for this purpose – to be able to communicate with remote parties securely without having complete trust in every single node on the way to the remote party. It relies on public-key cryptography, which makes it so that it is easy to encrypt messages with the public key, but extremely difficult (or practically impossible) to reverse the encryption without knowing the private key.
A browser which communicates with a server via HTTPS creates a link based on keys exchanged securely. Only the server and the browser know these keys, and so only the server and the browser can send and receive messages to each other.
Wireshark, even if it is running on your computer, is not running as a part of your browser and hence does not know the keys that the server and the browser agreed on. So it is impossible for it to read the traffic.
It may be somewhat surprising to know that even if somebody (Wireshark) can read all the data your browser exchanges with a server, it will not know the keys that the browser and server agreed on.
Traditionally, secure encrypted communication between two parties required that they first exchange keys by some secure physical channel, such as paper key lists transported by a trusted courier. The Diffie–Hellman key exchange method allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure channel. This key can then be used to encrypt subsequent communications using a symmetric key cipher.
Diffie-Hellman key exchange, Wikipedia

How to save a string safely in iOS?

I must save a string (a passphrase) in the keychain but the original string:
doesn't come from the server;
is not generated by the user;
it must be compared on a server (I send it over https);
So, the string must live somewhere in the app (hardcoded?).
I'm quite sure you can't prepare data for the keychain to be readily available for the app after it is installed, like you can just add a plist to the app bundle so that it can be loaded right away if the app is running (even if it's the first time it gets launched).
I have read about Data Protection: it allows applications that work with sensitive data to take advantage of encryption available on some devices. Is that the way to go? That is: I store my data into a text file, then I protect the file, then I retrieve my data from the file, then I save it to the keychain?
Any tip is appreciated.
If it is not possible to provide the string from outside (user input, a server) developer is forced to put it in the application bundle in some form. It can be hardcoded, stored in a file, or generated by a function. It means application has all necessary information to get/produce such a string. Thus it is not able to secure the information as good as encryption would do.
iOS apps are protected by Apple's DRM, so you can feel safe if someone copies your binary to Mac and starts disassembling it. However, if hacker has a jailbroken device there are tools to dump your application binary from memory to disk, unfortunately.
So it boils down to obfuscation. You could write a function that generates the string dynamically (e.g. a series of operations on hardcoded array of bytes and then convert it to the string). This will make your string harder to intercept by the hacker.
As main concern is with paraphrase or access token, it can be saved as encrypted data in keychain but this will be decrypted whenever we will send a request & it can be tracked on jailbroken devices.But using more agnostic algos to encrypt request data will increase API response time.However defining user based permissions at server side is best way as in worst case only 1 user's data can be tracked.
SSL Pinning - using challenge response authentication, we can prevent app from man in the middle attack. Yes, ssl pinning can be bypassed but it's not that easy & only possible on jailbroken devices.
Defining expiry time to few seconds could be another way to prevent user's data.Identifying source of request is also very important before granting permissions..
So by collaborating multiple ways we can try to make better system.
EDIT
Generally we encrypt data using 1 key as token & it can be decrypted once that key is revealed.
Asymmetric Encryption adds 1 more layer of encryption using public & private keys.
https://developer.apple.com/library/content/documentation/Security/Conceptual/Security_Overview/CryptographicServices/CryptographicServices.html#//apple_ref/doc/uid/TP30000976-CH3-SW12
here is one more example where random salt is used over token to encode data https://en.wikipedia.org/wiki/PBKDF2
Variants of this question have been discussed on SO a bunch of times already, and unfortunately you won't find a perfect answer, as there isn't one.
Essentially, you want to ship authentication credentials in your app, i.e. you bundle a secret into it. This means that no matter what you do, there's a possibility that an attacker retrieves it via reverse engineering. Even if you encrypt it with a hard algorithm that is technically secure enough, at some point your app decrypts it and since the app might be in the hands of an attacker, they will be able to sniff the secret.
This means in the end you can only try to make it hard for them by basically obfuscating the way in which you handle the secret ("make sniffing complicated"). Bundling an encrypted file that gets decrypted and then packed into the keychain seems not like a bad idea to me for a start, but keep in mind that for somebody looking at your app, especially on a jailbroken iPhone, this vanishing file can be a good first hint. Also, deleting it doesn't really help, as one re-install easily restores it.
Another idea could be to use On-Demand Resources to distribute your secret, this might also make it easier to replace it with an updated version in case your secret gets compromised. I am not that familiar with on-demand resources myself, though, so I can't tell you how suited they would be for actually revoking things.
This all assumes that you have no way of implementing an authentication mechanism based on user input. That way an attacker could only steal their own password (assuming they don't steal someone else's iPhone...) and not a vital part of your entire app (which could potentially affect all users).
Other SO answers from my bookmarks that might help you are these:
https://stackoverflow.com/a/9183066/710041
https://stackoverflow.com/a/9448821/710041
Okay, after re-reading your last comment under the question again, here's a concrete suggestion. I don't know why you need this second password/token at all if you're already having user authentication (you talk about them logging in), but here you go:
You don't bundle a token/pass together with the app at all. When first running your app, user's have to log in anyways (if I got you right), so your server can be involved and this is where you start.
During this login, the server generates a token/password and will send this to the user (depending on your exact implementation/custom protocol this might be done in a second request/response done by the app that uses the same user credentials or you put it into the headers of the response to the very first request sent by the app). Note that you don't need to encrypt this as long as you use https, as this already encrypts this data. So the channel by which your token arrives within your app is secure.
The app then saves this token/pass in the keychain immediately. This is as good encrypted as it gets on a mobile device. Do not save the token in anything else, even temporarily. The pass only ever exists in plain when it's in memory (you can't avoid that).
You use that token for whatever you need it (I am actually wondering why you need it if you're already using https and a user login system at all).
All in all this sounds like a pretty standard pseudo-OAuth-like token approach, if you're just wanting to use the token to avoid always relying on the user credentials (username and password) in each request. Technically you could also just save username and password in the keychain and always get those for each request. Usually these tokens have a limited time-to-live after which they become invalid anyways and the app has to rely on username and password again to get a new one anyways.
The potential downside of a token is if it's static and not user-bound or if it doesn't have this time-to-live limit. You would have to generate this in a clever way on the server and obviously note which user uses which token. That way you can pinpoint security breaches and react accordingly (instead of suddenly shutting down the server for all users by invalidating your one and only token). Again, I don't see why you need this, though.
Regarding a man-in-the-middle attack: A token, be it app-bundled (which is a risk in itself) or server generated, doesn't in itself protect against that. I have no idea what your boss would aim for here, but perhaps I'm missing some information. In general, https already protects you from this (well, usually only the server is authenticated, but if you already have a username and password system, you should be fine for the client side, too). It's actually a big point of it in general. To me this sounds more and more like something in your original problem is simply a misunderstanding of the existing infrastructure and/or a "boss-induced" problem... :)
What you can do is have your parameters encrypted using AES 256 encryption while calling an API, then the server decrypts the parameters and again sends encrypted response.You can decrypt and read the response, provided your server and app shares the same key used for encryption and decryption.
I had a similar functionality in my app so my Util class encrypts and decrypts the request and response using the following code,
class func encrypt (stringToEncrypt: String) -> String {
let messageData = stringToEncrypt.data(using: .utf8)
let encryptedBytes = try! AES(key: "abcdefghijklmnopqrstuvwxyz012345", iv: "abcdefghijklmost").encrypt([UInt8](messageData!))
return encryptedBytes.toBase64()!
}
class func decrypt ( message: String) -> String {
let messageData = Data(base64Encoded: message, options: .ignoreUnknownCharacters)
let decryptedBytes: [UInt8] = try! AES(key: "abcdefghijklmnopqrstuvwxyz012345", iv: "abcdefghijklmost").decrypt([UInt8](messageData!))
let unencryptedString = String(bytes: decryptedBytes, encoding: .utf8)
return unencryptedString!
}
Again this is just a suggestion you can do it using other ways also.
For saving some string values in Keychain you can make use of a pod library
pod 'SSKeychain'
You can save a string to keychain as follows
let appName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
SSKeychain.setAccessibilityType(kSecAttrAccessibleAlways)
SSKeychain.setPassword(stringToSave, forService: appName, account: "MyAppName")
Also retrieve the same using
let appName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
let stringRetrieved = SSKeychain.passwordForService(appName, account: "MyAppName")
Import these once you installed the above pod
import SystemConfiguration
import SSKeychain
This will be retained even if the app the deleted and re-installed. If you want additional encryption you can make use of any encryption algorithm this one is useful
AES encryption in swift
Encryption techniques may help to get solve the requirement. Here is the simple elaboration how we can maintain a keys on top of the Diffie–Hellman key exchange encryption techniques.
Prerequisites:
Maintain public and private key pairs on both the sides client and server.
Algorithm or logic to generate private keys should use same for both client and server end.
Logic to break the final acquire keys to compare the own string.
Process:
Both app and backend should have a common public key what ever it is in this case just take it as application name like MyApplication.
public key: MyApplication
Should generate private keys on the both the ends by using some encryption process or logic. For suppose generate random number as private key like below.
Suppose App private key is: 10
Suppose Backend private key is: 90
Generate exchange keys on both app and backend by following some kind of algorithm. Here just to combine both public and private keys like
App final key: MyApplication + 10
Backend final key: MyApplication + 90
Exchange the keys in between app and backend.
App Got key: MyApplication + 90
Backend Got key: MyApplication + 10
Compare the received key with own by using some kind of technique like
i. Generated new App key by combining app private key and App Got key like: MyApplication + 90 + 10
ii. Generated new Backend key by combining Backend private key and Backend Got key like: MyApplication + 10 + 90
To Check both the key are same need follow to logic For example here Just add last two number in the keys result will be like
App owned key: MyApplication + 100
App acquired key: MyApplication + 100
BackEnd owned key: MyApplication + 100
BackEnd acquired key: MyApplication + 100
Hola finally both backend and app has the same key.
Depends on the requirements needs maintain different private key per each session and store it on keychains. or make one private key and store it on app side.
NOTE: This description illustrates just an overview how to maintain the keys, It may involves lot of logics and also has a provision to break up the keys by others that totally depends on encryptions and logics using to generate and break the keys.
References:
https://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange
https://security.stackexchange.com/questions/7390/how-to-properly-encrypt-a-communication-channel-between-a-client-and-a-server-w

Securing a Password in a Background Job in Ruby

I have a access token that is stored encrypted as an ENV variable on a server. When someone wants to generate a report - they send up a password which is used to decrypt the encrypted access token (currently using ActiveSupport::MessageEncryptor) then the access token is used to make some API calls to a third party needed to generate the report.
The issue I'm running into is the network API call to the third party is slow (a few minutes) and causing web requests to timeout. The project has Sidekiq + ActiveJob integrated and I thought it'd be great to queue a job (then the slow runtime won't matter).
I'm unclear now how to properly handle the password. I can't use the password as an argument for the job (since it then gets stored in Redis). Likewise I can't put the decrypted access token (for the same reason). Do I have any options? If the third party let me convert the encrypted access key into a limited use / expiring key via a quick API I could do that prior to enqueueing - but I don't beleive that is an option. Any other options?
Sidekiq Enterprise supports encrypted job data, designed to solve exactly the problem you have.
https://github.com/mperham/sidekiq/wiki/Ent-Encryption

OAuth test server / application

I am thinking about creating an OAuth library in LabVIEW, but for testing this during development I would like to use some test server, without overloading an existing service that has real users.
Is there such a server or is there an easy server application (Linux or Windows) that I can run myself?
http://term.ie/oauth/example/index.php is a live example of the php code found in http://oauth.googlecode.com/svn/code/php/example/.
The endpoints are:
http://term.ie/oauth/example/request_token.php
http://term.ie/oauth/example/access_token.php
http://term.ie/oauth/example/echo_api.php
The consumer key and secret are:
Consumer Key: key
Consumer Secret: secret
The tokens returned are:
Request token: requestkey
Request secret: requestsecret
and
Access token: accesskey
Access secret: accesssecret
I tested it with it's own client code at http://term.ie/oauth/example/client.php and it worked with HMAC and PLAINTEXT signature methods.
RSA signature would require the public and private keys used in the test server found here:
http://oauth.googlecode.com/svn/code/php/OAuth_TestServer.php
For a quick and dirty test this'll probably work, if you're worried about using someone elses server, it should be fairly easy to deploy the code from http://oauth.googlecode.com/svn/code/php/ locally or on a server you have access to that is running php.
you can try OAuth.io and their open source daemon oauthd on Github : https://github.com/oauth-io/oauthd
You can try ApiFest OAuth 2.0 Server (https://github.com/apifest/apifest-oauth20). Follow the steps described to start the server. Enjoy!

Resources