Created
June 15, 2017 23:31
-
-
Save anler/c684766fd95ace050a911f426aea6c71 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@scala.annotation.implicitNotFound("${EncryptKeyType} encrypted messages cannot be decrypted with ${DecryptKeyType}") | |
trait CanDecrypt[DecryptKeyType, EncryptKeyType] | |
object CanDecrypt { | |
implicit val pkOnSk = new CanDecrypt[PK, SK] {} | |
implicit val skOnPk = new CanDecrypt[SK, PK] {} | |
} | |
sealed trait PK // public key type | |
sealed trait SK // private key type | |
final case class Key [KeyType](jkey: java.security.Key) | |
// carries key type info ^^^^^^ | |
final case class Secret[KeyType](bytes: Array[Byte]) | |
// ^^^^^^^ | |
// carries key type used for encryption | |
def generateKeyPair: (Key[PK], Key[SK]) = { | |
val gen = java.security.KeyPairGenerator.getInstance("RSA") | |
val pair = gen.generateKeyPair | |
(Key(pair.getPublic), Key(pair.getPrivate)) | |
} | |
def encrypt[A](key: Key[A], data: Array[Byte]): Secret[A] = { | |
val cipher = javax.crypto.Cipher.getInstance("RSA") | |
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key.jkey) | |
Secret(cipher.doFinal(data)) | |
} | |
def decrypt[A, B](key: Key[A], secret: Secret[B])(implicit ev: CanDecrypt[A, B]): Array[Byte] = { | |
val cipher = javax.crypto.Cipher.getInstance("RSA") | |
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key.jkey) | |
cipher.doFinal(secret.bytes) | |
} | |
val data = "phantom".getBytes | |
val (pk, sk) = generateKeyPair | |
val secret = encrypt(pk, data) | |
decrypt(sk, encrypt(pk, data)).toVector == data.toVector // true | |
decrypt(pk, encrypt(sk, data)).toVector == data.toVector // true | |
// If we try to decrypt with the same encryption key: | |
// decrypt(sk, encrypt(sk, data)).toVector == data.toVector) | |
// we will get a compile error with the message: | |
// SK encrypted messages cannot be decrypted with SK |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment