more docs
This commit is contained in:
parent
165cd07353
commit
f08653715b
@ -12,12 +12,48 @@ import net.sergeych.crypto2.Container.Companion.createWith
|
|||||||
* Multi-key encrypted container with simple adding new keys function that does not need to
|
* Multi-key encrypted container with simple adding new keys function that does not need to
|
||||||
* know all existing keys, e.g., you can add recipients to the container data if you can
|
* know all existing keys, e.g., you can add recipients to the container data if you can
|
||||||
* decrypt it. This is sometimes very important to be able to add recipients to the message
|
* decrypt it. This is sometimes very important to be able to add recipients to the message
|
||||||
* keeping existing recipients you know no keys of.
|
* keeping existing recipients you know no keys of, or update the message when only one of the
|
||||||
*
|
* keys is known.
|
||||||
* See:
|
*
|
||||||
* - [createWith] for more on create a new container
|
* - [createWith] for more on create a new container
|
||||||
* - [addRecipients] and various [plus] operators to add recipients
|
|
||||||
* - [decryptWith] to decrypt
|
* - [decryptWith] to decrypt
|
||||||
|
* - [addRecipients] and various [plus] operators to add recipients
|
||||||
|
* - [updateData] to change decrypted content for the same recipient keys
|
||||||
|
*
|
||||||
|
* Some rules:
|
||||||
|
*
|
||||||
|
* When adding public key recipient, it is faster to use your known [Asymmetric.SecretKey], but you
|
||||||
|
* can stay anonymous by just adding [Asymmetric.PublicKey] only.
|
||||||
|
*
|
||||||
|
* Put your data in [SealedBox] if you need to authenticate message origin and timestamp, then put
|
||||||
|
* the sealed box in the [Container], this will conceal signers from attack. In the case you need to
|
||||||
|
* prove message origin without disclosing its content, put the [Container] in the [SealedBox].
|
||||||
|
* Everybody will see who and when have it signed, but only intended recipients could read it.
|
||||||
|
*
|
||||||
|
* Sample:
|
||||||
|
* ```kotlin
|
||||||
|
* // create container fpr p3.public key destination using our secret key (for speed)
|
||||||
|
* var c = Container.createWith(data, p1.secretKey to p3.publicKey)
|
||||||
|
*
|
||||||
|
* // imitation of receiving an encrypted container in binary form
|
||||||
|
* // so it is not decrypted
|
||||||
|
* c = Container.decode(c.encoded)
|
||||||
|
*
|
||||||
|
* // decrypt it with the right key
|
||||||
|
* c.decryptWith(p3.secretKey)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* // add more keys to it: 2 symmetric, public anonymous, and secret-to-public pair (faster)
|
||||||
|
* c = c + symmetricKey1 + symmetricKey2 + herPublicKey + (MySecretKey to hisPublicKey)
|
||||||
|
*
|
||||||
|
* // and update data in it (it will be encrypted too), adding random bytes, at least 100 and no
|
||||||
|
* // more than 200, to make size analysis attack almost impossible
|
||||||
|
* // in the 100 to 200
|
||||||
|
* c = c..updateData(data2, 100..22)
|
||||||
|
*
|
||||||
|
* // now we can send it over the network
|
||||||
|
* sendOVerTheNetwork(c.encoded)
|
||||||
|
*```
|
||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
sealed class Container {
|
sealed class Container {
|
||||||
@ -83,6 +119,10 @@ sealed class Container {
|
|||||||
*/
|
*/
|
||||||
operator fun plus(pair: Pair<Asymmetric.SecretKey, Asymmetric.PublicKey>) = addRecipients { key(pair) }
|
operator fun plus(pair: Pair<Asymmetric.SecretKey, Asymmetric.PublicKey>) = addRecipients { key(pair) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the data in the decrypted container. It keeps the same set of keys and update
|
||||||
|
* the data only.
|
||||||
|
*/
|
||||||
abstract fun updateData(newPlainData: UByteArray,randomFill: IntRange?=null): Container
|
abstract fun updateData(newPlainData: UByteArray,randomFill: IntRange?=null): Container
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -241,17 +281,17 @@ sealed class Container {
|
|||||||
*
|
*
|
||||||
* ```kotlin
|
* ```kotlin
|
||||||
* Container.create(plainData) {
|
* Container.create(plainData) {
|
||||||
* // optional: add a random filling from 10 to 20 bytes
|
* // optional: add a random filling from 10 to 20 bytes
|
||||||
* fill( 10 .. 20 )
|
* fill( 10 .. 20 )
|
||||||
*
|
*
|
||||||
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
||||||
*
|
*
|
||||||
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
||||||
*
|
*
|
||||||
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
||||||
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
||||||
* // to know it was me who added them to this container.
|
* // to know it was me who added them to this container.
|
||||||
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
|
|
||||||
@ -380,17 +420,17 @@ sealed class Container {
|
|||||||
* Usage sample:
|
* Usage sample:
|
||||||
* ```kotlin
|
* ```kotlin
|
||||||
* Container.create(plainData) {
|
* Container.create(plainData) {
|
||||||
* // optional: add a random filling from 10 to 20 bytes
|
* // optional: add a random filling from 10 to 20 bytes
|
||||||
* fill( 10 .. 20 )
|
* fill( 10 .. 20 )
|
||||||
*
|
*
|
||||||
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
||||||
*
|
*
|
||||||
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
||||||
*
|
*
|
||||||
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
||||||
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
||||||
* // to know it was me who added them to this container.
|
* // to know it was me who added them to this container.
|
||||||
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
* At least one key should be provided.
|
* At least one key should be provided.
|
||||||
|
@ -195,11 +195,8 @@ class ContainerTest {
|
|||||||
initCrypto()
|
initCrypto()
|
||||||
val syk1 = SymmetricKey.random()
|
val syk1 = SymmetricKey.random()
|
||||||
val syk2 = SymmetricKey.random()
|
val syk2 = SymmetricKey.random()
|
||||||
val syk3 = SymmetricKey.random()
|
|
||||||
val p1 = Asymmetric.generateKeys()
|
val p1 = Asymmetric.generateKeys()
|
||||||
val p2 = Asymmetric.generateKeys()
|
|
||||||
val p3 = Asymmetric.generateKeys()
|
val p3 = Asymmetric.generateKeys()
|
||||||
val p4 = Asymmetric.generateKeys()
|
|
||||||
val data = "Translating the name 'Sergey Chernov' from Russian to archaic Sanskrit would be 'Ramo Krishna'"
|
val data = "Translating the name 'Sergey Chernov' from Russian to archaic Sanskrit would be 'Ramo Krishna'"
|
||||||
.encodeToUByteArray()
|
.encodeToUByteArray()
|
||||||
|
|
||||||
@ -273,6 +270,7 @@ class ContainerTest {
|
|||||||
val p2 = Asymmetric.generateKeys()
|
val p2 = Asymmetric.generateKeys()
|
||||||
val p3 = Asymmetric.generateKeys()
|
val p3 = Asymmetric.generateKeys()
|
||||||
val p4 = Asymmetric.generateKeys()
|
val p4 = Asymmetric.generateKeys()
|
||||||
|
val p5 = Asymmetric.generateKeys()
|
||||||
val data = "Translating the name 'Sergey Chernov' from Russian to archaic Sanskrit would be 'Ramo Krishna'"
|
val data = "Translating the name 'Sergey Chernov' from Russian to archaic Sanskrit would be 'Ramo Krishna'"
|
||||||
.encodeToUByteArray()
|
.encodeToUByteArray()
|
||||||
|
|
||||||
@ -296,7 +294,7 @@ class ContainerTest {
|
|||||||
c.decryptWith(p3.secretKey)
|
c.decryptWith(p3.secretKey)
|
||||||
|
|
||||||
val data2 = "Cocktails have a delicious, complex taste".encodeToUByteArray()
|
val data2 = "Cocktails have a delicious, complex taste".encodeToUByteArray()
|
||||||
c = (c + syk3 + (p1.secretKey to p4.publicKey)).updateData(data2)
|
c = (c + syk3 + p5.publicKey + (p1.secretKey to p4.publicKey)).updateData(data2)
|
||||||
expectNotOpen(syk2, syk1, p1.secretKey, p2.secretKey )
|
expectNotOpen(syk2, syk1, p1.secretKey, p2.secretKey )
|
||||||
expectOpen(data2, syk3, p3.secretKey, p4.secretKey)
|
expectOpen(data2, syk3, p3.secretKey, p4.secretKey)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user