Help with key management and android/ios library for signing documents

Hi there,

We are creating an app to share content in an offline/online scenario. We are planning to use Couchbase with some library that may sign data. We want people be able to use our app even without going to Internet and if possible they can use it also online. We need our app be able to sign every content that people create.

I need your help suggesting how to store keys in the app and in the server, and if there is something already made in this way.

Also we need help finding a library that may sign all data to be stored in Couchbase lite in Android and iOS. I found openkeychain, but it doesn’t seem that I can take from there only the library that is needed to sign the content.

We will really appreciate your suggestions.

Have a big hug,

Carlos.

You may be interested in this related post. [quote=“cmgver, post:1, topic:13607”]
I need your help suggesting how to store keys in the app and in the server, and if there is something already made in this way.
[/quote]

This is an application level decision outside the scope of of couchbase. But here are some suggestions w.r.t. key storage - on iOS, you can store in keychain. On Android , you may want to look into keystore.

1 Like

I’ve done some prototyping of signed documents, a few years ago.

For a library, I’d recommend libSodium. It’s cross-platform and easy to use. It implements public-key crypto with the efficient curve25519 and ed25519 algorithms.

You’ll want the device to generate a key-pair on first launch, and store it securely, e.g. in the iOS keychain. The public key should be written to a document so that other clients can discover it.

Signing is the hard part, because the document has to be transformed into a data blob to be run through the algorithm, and that blob has to be identical (“canonical”) no matter who creates it. What I did was encode it as JSON using a special encoder that always writes dictionary keys in sorted order. Also, when verifying the signature you have to skip the property containing the signature since it was added after signing!

1 Like

I found my more detailed spec on how to sign documents: https://github.com/couchbase/couchbase-lite-ios/wiki/Signed-Documents

Hi Jens, thanks for answering. I’m reviewing the other answers, I wanted to say that we already saw that spec and it was really helpful but there is only a general info about things to take care when signing documents, not resources or libraries.

Jens and Priya, thanks a lot for your answers, you have been really helpful :slight_smile: Jens if you have the code you made prototyping signed documents, it would be really helpful if we can take a look at it, is it public? Thanks again!!

The prototype code is here. I haven’t used it in a year or two, but I think it should still build/run. File issues if you run into any problems.

1 Like

super thanks jens :slight_smile:

Do you have any suggestions about the safest way to store in Android and iOS the private key that libsodium generated? I saw Keystore but I don’t trust it at all because an attacker may gain access to the content of it in a rooted system. Our app will be used in offline environments where many people root their phone. Thanks!!!

On iOS, use the Keychain. My code has support for that.
I have no knowledge of Android APIs so I can’t help you there.

If the phone is rooted, then pretty much all bets are off and IMHO, that’s a risk a user assumes as soon as they choose to do that.
As suggested above, your option in Android is the keystore provider. Unfortunately, as you noted, software based solutions are vulnerable to attacks. On devices that support it, you can use hardware backed keystone . Maybe, if your workflow allows, you can enforce user authentication for key access

If you’re really worried, you can make the user responsible for storing the key, so they have to type in a passphrase on launch. But (a) users hate doing this, and (b) they tend to react by choosing short easy-to-type passwords that are easy to guess by brute-force.

If you want to go this route, it’s pretty easy. Use a key derivation function combined with salt to turn the user’s password into a value you can use as a symmetric key, then use that to encrypt the real key in a file.

Priya and Jens, thanks again for your answers.

This is the offline/online scenario we are thinking to use: If the app is offline since the first time then it will create a private key to sign all couchbase documents and the public key will go there attached every time a document is shared via bluetooth or wifi. Those keys will be created the first time the users uses the app.

The app will come only with a sub private key and a public key from our server to encrypt the pass of the user that will be entered the first time he uses the app and that encrypted pass will be sent to our server to create the user’s account when they go to Internet. More stuff will come later like the api token.

My question is, what do people like Facebook and everybody else do with their apps when they are in a rooted scenario? Where do they keep the secrets? They just use obscure mixed hidden strategies to obfuscate their secrets or there is a way to really keep them safe?

Jens, Keychain is safe even if the iphone is jailbroken?

Sorry for so many questions :slight_smile:

that encrypted pass will be sent to our server to create the user’s account when they go to Internet.

I’m not sure I understand this. But it seems like more than you need to just register an account; you can do that with a simple POST to your application server (not SG) containing a username and password. As long as you do this over SSL it’s secure.

what do people like Facebook and everybody else do with their apps when they are in a rooted scenario?

I don’t know if apps do anything specific. I would guess that generally they assume that the OS is intact and don’t worry about workarounds for broken OS’s.

Jens, Keychain is safe even if the iphone is jailbroken?

I don’t know, but I would assume not. To be blunt, if the OS has (intentionally) been damaged to disable a lot of its core security features, all bets are off; you can’t make any security claims about it at all anymore. But I don’t think that it’s your responsibility to try to work around that; it’s basically the end user’s fault.

@cmgver If you are paranoid about jailbroken devices, you may want to look at Google’s [Safetynet API (https://developer.android.com/training/safetynet/index.html) for attesting to the validity of the Android device on which the app is installed . The safetyAPIs can indicate if the device is jailbroken and if it passes basic integrity and profile checks. You can use it in conjunction with other tamper detection techniques (like looking for the su binary in /system partition). But there isn’t an equivalent for iOS.

And +1 to everything Jens has indicated above. App Developers don’t typically worry about trying to deal with jailbroken phones. Apps with stringent security requirements may use tamper detection techniques mentioned .