forked from sergeych/crypto2
fix #1 UniversalPrivateKey & UniversalPublicKey
This commit is contained in:
1 parent
194fe22afa
commit
640ceb448e
9 files changed
+131
-4
No files matched your search
@@ -20,6 +20,8 @@ import net.sergeych.crypto2.Container.Companion.createWith
|
||||
* - [addRecipients] and various [plus] operators to add recipients
|
||||
* - [updateData] to change decrypted content for the same recipient keys
|
||||
*
|
||||
* Note that container _is serialized encrypted_.
|
||||
*
|
||||
* Some rules:
|
||||
*
|
||||
* When adding public key recipient, it is faster to use your known [SecretKey], but you
|
||||
@@ -126,8 +128,9 @@ sealed class Container {
|
||||
abstract fun updateData(newPlainData: UByteArray, randomFill: IntRange? = null): Container
|
||||
|
||||
/**
|
||||
* Binary encoded version. It is desirable to include [Container] as an object, though,
|
||||
* especially when using custom serialization (Json, Boss, etc), it is serializable.
|
||||
* Binary encoded _encrypted_ version. It is desirable to include [Container] as an object, though,
|
||||
* especially when using custom serialization (Json, Boss, etc.), it is serializable. Note that
|
||||
* serialized data is always encrypted.
|
||||
* Still, if you need it in binary form, this is a shortcut. You can use [decode] or call
|
||||
* [BipackDecoder.decode] to deserialize the binary form.
|
||||
*/
|
||||
@@ -474,6 +477,12 @@ sealed class Container {
|
||||
inline fun <reified T> decrypt(cipherData: UByteArray, vararg keys: DecryptingKey): T? =
|
||||
decryptAsUBytes(cipherData, *keys)?.let { BipackDecoder.decode<T>(it.asByteArray()) }
|
||||
|
||||
inline fun <reified T> decrypt(cipherData: UByteArray, ring: UniversalRing): T? =
|
||||
decode(cipherData)
|
||||
.decryptWith(ring)?.let {
|
||||
BipackDecoder.decode<T>(it.asByteArray())
|
||||
}
|
||||
|
||||
fun decryptAsUBytes(cipherData: UByteArray, vararg keys: DecryptingKey): UByteArray? =
|
||||
decode(cipherData).decryptWith(*keys)
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@ enum class KeysmagicNumber(val label: String) {
|
||||
defaultSymmetric( "sym"),
|
||||
defaultSession( "ssn"),
|
||||
defaultVerifying( "ver"),
|
||||
|
||||
defaultSigningSecret( "sig"),
|
||||
|
||||
defaultUniversalPublic( "pub+"),
|
||||
defaultUniversalPrivate( "prv+"),
|
||||
;
|
||||
|
||||
}
|
||||
@@ -23,6 +23,8 @@ class SigningSecretKey(
|
||||
VerifyingPublicKey(Signature.ed25519SkToPk(keyBytes)).also { cachedPublicKey = it }
|
||||
}
|
||||
|
||||
override val magic: KeysmagicNumber = KeysmagicNumber.defaultSigningSecret
|
||||
|
||||
override fun sign(message: UByteArray): UByteArray = Signature.detached(message, keyBytes)
|
||||
|
||||
override fun seal(message: UByteArray, expiresAt: Instant?): Seal =
|
||||
|
||||
@@ -8,7 +8,6 @@ sealed class UniversalKey: KeyInstance {
|
||||
|
||||
abstract val keyBytes: UByteArray
|
||||
|
||||
|
||||
@Transient
|
||||
open val magic: KeysmagicNumber = KeysmagicNumber.Unknown
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.sergeych.crypto2
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
/**
|
||||
* Combination of private/secret keys suitable for both decryption and signing.
|
||||
*
|
||||
* It contains two cryptographically independent keys to raise security to a maximum.
|
||||
* Any converted keys poses a threat while technically possible so we avoid it.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("uprv")
|
||||
class UniversalPrivateKey(
|
||||
val signingKey: SigningSecretKey,
|
||||
val decryptingKey: SecretKey
|
||||
) : UniversalKey(), DecryptingKey by decryptingKey, SigningKey by signingKey {
|
||||
|
||||
override val keyBytes by lazy { signingKey.keyBytes + decryptingKey.keyBytes }
|
||||
|
||||
@Transient
|
||||
override val magic = KeysmagicNumber.defaultUniversalPrivate
|
||||
|
||||
/**
|
||||
* Important! Private key combines signing and decrypting keys, but uses
|
||||
* it of the decrypting one to be used in keyring.
|
||||
*/
|
||||
@Transient
|
||||
override val id: KeyId = decryptingKey.id
|
||||
|
||||
/**
|
||||
* Corresponding public key able to verify amd encrypt data created by this
|
||||
* private key.
|
||||
*/
|
||||
val publicKey by lazy {
|
||||
UniversalPublicKey(signingKey.verifyingKey, decryptingKey.publicKey)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Generate 2 new random keys (4 key pairs under the hood) to securely signd and
|
||||
* decrypt data.
|
||||
*/
|
||||
fun new() = UniversalPrivateKey(SigningSecretKey.new(), SecretKey.new())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.sergeych.crypto2
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
/**
|
||||
* Combination of public keys suitable for both encryption and verification. A counterpart
|
||||
* of the [UniversalPrivateKey], available also as [UniversalPrivateKey.publicKey].
|
||||
*
|
||||
* When using [UniversalRing] and [Container], data encrypted with instances og this class
|
||||
* can be decrypted with rings containing the corresponding [UniversalPrivateKey].
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("upub")
|
||||
class UniversalPublicKey(
|
||||
val verifyingKey: VerifyingPublicKey,
|
||||
val encryptingKey: PublicKey
|
||||
): UniversalKey(), VerifyingKey by verifyingKey, EncryptingKey by encryptingKey{
|
||||
|
||||
override val keyBytes by lazy { verifyingKey.keyBytes + encryptingKey.keyBytes }
|
||||
|
||||
@Transient
|
||||
override val magic = KeysmagicNumber.defaultUniversalPublic
|
||||
|
||||
/**
|
||||
* Important! Private key combines signing and decrypting keys, but uses
|
||||
* it of the decrypting one to be used in keyring.
|
||||
*/
|
||||
@Transient
|
||||
override val id: KeyId = encryptingKey.id
|
||||
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user