-
-
Save jidolstar/9ca129d4f3e9632b12a820f0784eb353 to your computer and use it in GitHub Desktop.
| package chela.spring.core; | |
| import javax.crypto.Cipher; | |
| import javax.crypto.spec.IvParameterSpec; | |
| import javax.crypto.spec.SecretKeySpec; | |
| import java.util.Base64; | |
| final public class ChCrypto { | |
| final static Base64.Encoder encorder = Base64.getEncoder(); | |
| final static Base64.Decoder decorder = Base64.getDecoder(); | |
| static private Cipher cipher(int opmode, String secretKey) throws Exception{ | |
| if(secretKey.length() != 32) throw new RuntimeException("SecretKey length is not 32 chars"); | |
| Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
| SecretKeySpec sk = new SecretKeySpec(secretKey.getBytes(), "AES"); | |
| IvParameterSpec iv = new IvParameterSpec(secretKey.substring(0, 16).getBytes()); //0~16은 서버와 합의! | |
| c.init(opmode, sk, iv); | |
| return c; | |
| } | |
| static public String encrypt(String str, String secretKey){ | |
| try{ | |
| byte[] encrypted = cipher(Cipher.ENCRYPT_MODE, secretKey).doFinal(str.getBytes("UTF-8")); | |
| return new String(encorder.encode(encrypted)); | |
| }catch(Exception e){ | |
| return null; | |
| } | |
| } | |
| static public String decrypt(String str, String secretKey){ | |
| try{ | |
| byte[] byteStr = decorder.decode(str.getBytes()); | |
| return new String(cipher(Cipher.DECRYPT_MODE, secretKey).doFinal(byteStr),"UTF-8"); | |
| }catch(Exception e){ | |
| return null; | |
| } | |
| } | |
| } |
| package chela.spring.core | |
| import java.util.Base64 | |
| import javax.crypto.Cipher | |
| import javax.crypto.spec.IvParameterSpec | |
| import javax.crypto.spec.SecretKeySpec | |
| object ChCrypto{ | |
| @JvmStatic fun aesEncrypt(v:String, secretKey:String) = AES256.encrypt(v, secretKey) | |
| @JvmStatic fun aesDecrypt(v:String, secretKey:String) = AES256.decrypt(v, secretKey) | |
| } | |
| private object AES256{ | |
| private val encorder = Base64.getEncoder() | |
| private val decorder = Base64.getDecoder() | |
| private fun cipher(opmode:Int, secretKey:String):Cipher{ | |
| if(secretKey.length != 32) throw RuntimeException("SecretKey length is not 32 chars") | |
| val c = Cipher.getInstance("AES/CBC/PKCS5Padding") | |
| val sk = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), "AES") | |
| val iv = IvParameterSpec(secretKey.substring(0, 16).toByteArray(Charsets.UTF_8)) | |
| c.init(opmode, sk, iv) | |
| return c | |
| } | |
| fun encrypt(str:String, secretKey:String):String{ | |
| val encrypted = cipher(Cipher.ENCRYPT_MODE, secretKey).doFinal(str.toByteArray(Charsets.UTF_8)) | |
| return String(encorder.encode(encrypted)) | |
| } | |
| fun decrypt(str:String, secretKey:String):String{ | |
| val byteStr = decorder.decode(str.toByteArray(Charsets.UTF_8)) | |
| return String(cipher(Cipher.DECRYPT_MODE, secretKey).doFinal(byteStr)) | |
| } | |
| } |
| <?php | |
| final class ChCrytpo{ | |
| static private function checkCryptKey($secretKey){ | |
| if(strlen($secretKey) != 32) throw new Exception('"SecretKey length is not 32 chars"'); //무조건 32byte되도록 로직을 바꿀 수 있음 (2기종간 합의 해야함) | |
| $iv = substr($secretKey, 0, 16); //IV는 2 기종간 합의하려면 이 규칙을 세울 필요 있음 | |
| return [$secretKey, $iv]; | |
| } | |
| static function encrypt($v, $secretKey){ | |
| $k = self::checkCryptKey($secretKey); | |
| return openssl_encrypt($v, 'aes-256-cbc', $k[0], 0, $k[1]); | |
| } | |
| static function decrypt($v, $secretKey){ | |
| $k = self::checkCryptKey($secretKey); | |
| return openssl_decrypt($v, 'aes-256-cbc', $k[0], 0, $k[1]); | |
| } | |
| } |
thank you a lot.
Hello !
I improve your encription function, adding random iv.
Here is the result:
import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import java.security.MessageDigest;
object ChCrypto{
@JvmStatic fun aesEncrypt(v:String, secretKey:String) = AES256.encrypt(v, secretKey)
@JvmStatic fun aesDecrypt(v:String, secretKey:String) = AES256.decrypt(v, secretKey)
}
private object AES256{
fun hash(): String {
val bytes = this.toString().toByteArray()
val md = MessageDigest.getInstance("SHA-256")
val digest = md.digest(bytes)
return digest.fold("", { str, it -> str + "%02x".format(it) })
}
fun getRandomString(length: Int) : String {
val charset = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz0123456789"
return (1..length)
.map { charset.random() }
.joinToString("")
}
private val encorder = Base64.getEncoder()
private val decorder = Base64.getDecoder()
private fun cipher(opmode:Int, secretKey:String, algo:String):Cipher{
if(secretKey.length != 32) throw RuntimeException("SecretKey length is not 32 chars")
val c = Cipher.getInstance("AES/CBC/PKCS5Padding")
val sk = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), "AES")
val iv = IvParameterSpec(algo.toByteArray(Charsets.UTF_8))
c.init(opmode, sk, iv)
return c
}
fun encrypt(str:String, secretKey:String):String{
val iv = getRandomString(16)
val encrypted = cipher(Cipher.ENCRYPT_MODE, secretKey, iv).doFinal(str.toByteArray(Charsets.UTF_8))
return iv.plus(":").plus(String(encorder.encode(encrypted)))
}
fun decrypt(str:String, secretKey:String):String{
val byteStr = decorder.decode(str.toByteArray(Charsets.UTF_8))
return String(cipher(Cipher.DECRYPT_MODE, secretKey, "algo").doFinal(byteStr))
}
}
fun main() {
val ket = 'your_key'
print(ChCrypto.aesEncrypt("encriptada - cambiada", key))
}
And here are analog encription and decription in PHP:
function encrypt($data, $password){
$iv = substr(sha1(mt_rand()), 0, 16);
$password = sha1($password);
$salt = sha1(mt_rand());
$saltWithPassword = hash('md5', $password.$salt);
$encrypted = openssl_encrypt(
"$data", 'aes-256-cbc', "$saltWithPassword", null, $iv
);
$msg_encrypted_bundle = "$iv:$salt:$encrypted";
return $msg_encrypted_bundle;
}
function decrypt($msg_encrypted_bundle, $password){
$password = sha1($password);
$components = explode( ':', $msg_encrypted_bundle );
$iv = $components[0];
$salt = hash('md5', $password.$components[1]);
$encrypted_msg = $components[2];
$decrypted_msg = openssl_decrypt(
$encrypted_msg, 'aes-256-cbc', $salt, null, $iv
);
if ( $decrypted_msg === false )
return false;
return $decrypted_msg;
}
System.out.println("Thank you!")
Thanks for sharing. There's a typo in
encorder/decorder