暗号化
秘密鍵の生成
SecretKeySpecクラスを使用して秘密鍵を作成します。
val key = SecretKeySpec(["鍵として使用するbyte配列"], "AES")
// ex) val key = SecretKeySpec("0123456789ABCDEF".toByteArray(), "AES")
Cipherクラスのオブジェクトを作成
Cipher.getInstanceで暗号化アルゴリズムを指定してCipherクラスのオブジェクトを作成します。
引数には 暗号化アルゴリズム/動作モード/パディング
の書式で指定します。
詳しくは各ドキュメントを参照してください。
developer.android.com
docs.oracle.com
val cipher = Cipher.getInstance("algorithm/mode/padding")
// ex) val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
秘密鍵の初期化
Cipher.initでCipher.ENCRYPT_MODEを指定して秘密鍵を初期化します。
cipher.init(Cipher.ENCRYPT_MODE, key)
読み込みと書き出し
暗号化したいファイルの読み込んで暗号化し、そのデータを書き出します。
val fis = FileInputStream("./before.json")
val fos = FileOutputStream("./encrypto.byte")
val cos = CipherOutputStream(fos, cipher)
val a = ByteArray(8)
var i = fis.read(a)
while (i != -1) {
cos.write(a, 0, i)
i = fis.read(a)
}
cos.flush()
cos.close()
IVをつける
今回はモードをCBCに指定したので、暗号化する際にIV(initialization vector)というものが自動的に作られ使われます。
このIVは復号化の際に必要となるため、暗号化したデータの先頭にIVをつけます。
fos.write(cipher.getIV())
ソースコード全文
import java.io.FileInputStream
import java.io.FileOutputStream
import javax.crypto.Cipher
import javax.crypto.CipherInputStream
import javax.crypto.CipherOutputStream
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
fun main(args: Array<String>) {
val fis = FileInputStream("./before.json")
val key = SecretKeySpec("0123456789ABCDEF".toByteArray(), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, key)
val fos = FileOutputStream("./encrypto.byte")
val cos = CipherOutputStream(fos, cipher)
fos.write(cipher.getIV())
val a = ByteArray(8)
var i = fis.read(a)
while (i != -1) {
cos.write(a, 0, i)
i = fis.read(a)
}
cos.flush()
cos.close()
}
復号化
秘密鍵の生成
SecretKeySpecクラスを使用して秘密鍵を作成します。
val key = SecretKeySpec(["鍵として使用するbyte配列"], "AES")
// ex) val key = SecretKeySpec("0123456789ABCDEF".toByteArray(), "AES")
Cipherクラスのオブジェクトを作成
Cipher.getInstanceで暗号化アルゴリズムを指定してCipherクラスのオブジェクトを作成します。
引数には 暗号化アルゴリズム/動作モード/パディング
の書式で指定します。
val cipher = Cipher.getInstance("algorithm/mode/padding")
// ex) val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
IVの読み込み
IV用のbyte配列を用意して、ファイルのIV部分(先頭16byte)を格納します。
val iv = ByteArray(16)
fis.read(iv)
IvParameterSpecの生成
読み込んだIVからIvParameterSpecを生成します。
val ivspec = IvParameterSpec(iv)
秘密鍵の初期化
Cipher.initでCipher.DECRYPT_MODEを指定して秘密鍵を初期化します。
暗号化のときとは異なり、第三引数にIvParameterSpecを指定します。
cipher.init(Cipher.DECRYPT_MODE, key, ivspec)
読み込みと書き出し
ファイルを読み込んで復号化して、そのデータを書き出します。
val fis = FileInputStream("./encrypto.byte")
val cis = CipherInputStream(fis, cipher)
val reader = cis.bufferedReader()
val file = File("./after.json")
val fw = FileWriter(file)
var line: String? = reader.readLine()
while (line != null) {
fw.write(line)
line = reader.readLine()
}
reader.close()
fw.close()
ソースコード全文
import java.io.FileInputStream
import java.io.File
import java.io.FileWriter
import javax.crypto.Cipher
import javax.crypto.CipherInputStream
import javax.crypto.CipherOutputStream
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
fun main(args: Array<String>) {
val fis = FileInputStream("./encrypto.byte")
val key = SecretKeySpec("0123456789ABCDEF".toByteArray(), "AES")
val iv = ByteArray(16)
fis.read(iv)
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val ivspec = IvParameterSpec(iv)
cipher.init(Cipher.DECRYPT_MODE, key, ivspec)
val cis = CipherInputStream(fis, cipher)
val reader = cis.bufferedReader()
val file = File("./after.json")
val fw = FileWriter(file)
var line: String? = reader.readLine()
while (line != null) {
fw.write(line)
line = reader.readLine()
}
reader.close()
fw.close()
}
コマンドラインでの実行
コンパイル
encripto.kt、decrypto.ktをそれぞれkotlincコマンドでコンパイルしてjarファイルを作成します。
kotlinc encrypto.kt -include-runtime -d encrypto.jar
実行
kotlinコマンドもしくはjavaコマンドで作成したjarファイルを実行します。
kotlin encrypto.jar
java -jar encrypto.jar