Browse Source

Add end-to-end encryption

connman
Aditya Kulkarni 5 years ago
parent
commit
9875a4624c
  1. 1
      app/build.gradle
  2. 3
      app/src/main/AndroidManifest.xml
  3. 65
      app/src/main/java/com/adityapk/zcash/zqwandroid/DataModel.kt
  4. 2
      app/src/main/java/com/adityapk/zcash/zqwandroid/MainActivity.kt

1
app/build.gradle

@ -35,6 +35,7 @@ dependencies {
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.google.android.gms:play-services-vision:17.0.2'
implementation 'com.android.support:support-vector-drawable:28.0.0'
implementation 'com.github.joshjdevl.libsodiumjni:libsodium-jni-aar:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

3
app/src/main/AndroidManifest.xml

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="com.adityapk.zcash.zqwandroid">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
tools:replace="android:allowBackup"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"

65
app/src/main/java/com/adityapk/zcash/zqwandroid/DataModel.kt

@ -7,6 +7,9 @@ import com.beust.klaxon.Klaxon
import com.beust.klaxon.Parser
import com.beust.klaxon.json
import okhttp3.WebSocket
import org.libsodium.jni.NaCl
import org.libsodium.jni.Sodium
import java.math.BigInteger
object DataModel {
@ -24,6 +27,43 @@ object DataModel {
transactions = null
}
var secret : ByteArray? = null
var nonce : ByteArray? = null
fun ByteArray.toHexString() = joinToString("") { String.format("%02x", it) }
fun init() {
val sodium = NaCl.sodium()
secret = ByteArray(Sodium.crypto_hash_sha256_bytes())
Sodium.crypto_hash_sha256(secret, "secret".toByteArray(), "secret".toByteArray().size)
nonce = ByteArray(Sodium.crypto_box_noncebytes())
Sodium.randombytes_buf(nonce, Sodium.crypto_box_noncebytes())
val message = "test".toByteArray()
val noncelen = Sodium.crypto_secretbox_noncebytes().toLong()
val nonce = ByteArray(noncelen.toInt())
val ciphertextlen = Sodium.crypto_secretbox_macbytes() + message.size
val ciphertext = ByteArray(ciphertextlen)
val secret = ByteArray(Sodium.crypto_secretbox_keybytes())
Sodium.randombytes_buf(nonce, noncelen.toInt())
Sodium.randombytes(secret, Sodium.crypto_secretbox_keybytes())
println("Noncelen = $noncelen" )
println(BigInteger(nonce.toHexString(), 16))
var ret = Sodium.crypto_secretbox_easy(ciphertext, message, message.size, nonce, secret)
Log.i(TAG, ret.toString())
val decrypted = ByteArray(ciphertext.size - Sodium.crypto_secretbox_macbytes())
ret = Sodium.crypto_secretbox_open_easy(decrypted, ciphertext, ciphertextlen, nonce, secret)
Log.i(TAG, ret.toString())
println("Recovered message=" + String(decrypted))
}
fun parseResponse(response: String) : Boolean {
val json = Parser.default().parse(StringBuilder(response)) as JsonObject
@ -73,7 +113,7 @@ object DataModel {
}
fun makeAPICalls() {
ws?.send(json { obj("command" to "getInfo") }.toJsonString())
ws?.send(encrypt(json { obj("command" to "getInfo") }.toJsonString()))
ws?.send(json { obj("command" to "getTransactions")}.toJsonString())
}
@ -85,6 +125,29 @@ object DataModel {
}
fun encrypt(s : String) : String {
// Take the string, encrypt it and send it as the payload with the nonce in a Json string
val msg = s.toByteArray()
check(secret != null)
check(nonce != null)
val encrypted = ByteArray(msg.size + Sodium.crypto_secretbox_macbytes())
// Increment nonce
Sodium.sodium_increment(nonce, nonce?.size ?: 0)
val ret = Sodium.crypto_secretbox_easy(encrypted, msg, msg.size, nonce, secret)
if (ret != 0) {
println("Encryption failed")
}
val j = json { obj("nonce" to nonce?.toHexString(),
("payload" to encrypted.toHexString()))}
return j.toJsonString()
}
private val TAG = "DataModel"
}

2
app/src/main/java/com/adityapk/zcash/zqwandroid/MainActivity.kt

@ -38,6 +38,8 @@ class MainActivity : AppCompatActivity(), TransactionItemFragment.OnFragmentInte
// When creating, clear all the data first
setMainStatus("")
DataModel.init()
btnConnect.setOnClickListener {
val intent = Intent(this, QrReaderActivity::class.java)
intent.putExtra("REQUEST_CODE", QrReaderActivity.REQUEST_CONNDATA)

Loading…
Cancel
Save