java php c# 三種語言的AES加密互轉

java php c# 三種語言的AES加密互轉

java php c# 三種語言的AES加密互轉


資料來源:https://www.cnblogs.com/bangejingting/p/5600568.html

https://gist.github.com/resting/3421760


PHP 測試網頁: https://encode-decode.com/aes128-encrypt-online/


ECB模式,PKCS5Padding填充。注意注意注意java只支持16位的key!!!




php

<?php
function aes128Encrypt($key, $data) {
  if(16 !== strlen($key)) $key = hash('MD5', $key, true);
  $padding = 16 - (strlen($data) % 16);
  $data .= str_repeat(chr($padding), $padding);
  return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16)));
}
function aes128Decrypt($key, $data) {
  $data = base64_decode($data);
  if(16 !== strlen($key)) $key = hash('MD5', $key, true);
  $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
  $padding = ord($data[strlen($data) - 1]); 
  return substr($data, 0, -$padding); 
}
echo aes128Encrypt("00000000FF593EEB", "0501");
echo "</br>";
echo aes128Decrypt("00000000FF593EEB", aes128Encrypt("00000000FF593EEB", "0501"));
/*
輸出備份:
Y5MTre3MWDwP3Zj3+YWgEw==
0501
*/
?>

java

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class HelloWorld{
    // 加密
    public static String Encrypt01(String sSrc, String sKey) throws Exception {
        try{
            Base64.Encoder encoder = Base64.getEncoder();     
            if (sKey == null) {
                System.out.print("Key为空null");
                return null;
            }
            // 判断Key是否为16位
            if (sKey.length() != 16) {
                System.out.print("Key长度不是16位");
                return null;
            }
            byte[] raw = sKey.getBytes();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式"
            IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());//使用CBC模式,需要一个向量iv,可增加加密算法的强度
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(sSrc.getBytes());
            return encoder.encodeToString(encrypted);//此处使用BASE64做转码功能,同时能起到2次加密的作用。
        } catch(Exception e){
            return null;            // Always must return something
        }
    }

    // 解密
    public static String Decrypt01(String sSrc, String sKey) throws Exception {
        Base64.Decoder decoder = Base64.getDecoder();
        try {
            // 判断Key是否正确
            if (sKey == null) {
                System.out.print("Key为空null");
                return null;
            }
            // 判断Key是否为16位
            if (sKey.length() != 16) {
                System.out.print("Key长度不是16位");
                return null;
            }
            byte[] raw = sKey.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec("0102030405060708"
                    .getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 = decoder.decode(sSrc);//先用base64解密
            try {
                byte[] original = cipher.doFinal(encrypted1);
                String originalString = new String(original);
                return originalString;
            } catch (Exception e) {
                System.out.println(e.toString());
                return null;
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return null;
        }
    }
    
    /**
     * 加密源数据
     * 
     * @param input
     * @return
     */
    public static String encrypt02(String input) {
        byte[] crypted = null;
        Base64.Encoder encoder = Base64.getEncoder(); 
        try {
            byte[] raw = "00000000FF593EEB".getBytes();
            SecretKeySpec skey = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            crypted = cipher.doFinal(input.getBytes("UTF-8"));
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return new String(encoder.encodeToString(crypted));
    }

    /**
     * 解密源数据
     * 
     * @param input
     * @return
     */
    public static String decrypt02(String input) {
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] output = null;
        try {
            byte[] raw = "00000000FF593EEB".getBytes();
            SecretKeySpec skey = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skey);
            output = cipher.doFinal(decoder.decode(input));
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return new String(output);
    }
     public static void main(String []args){
        System.out.println("Hello World");
        try{
            System.out.println(Encrypt01("0501", "00000000FF593EEB"));
            System.out.println(Decrypt01(Encrypt01("0501", "00000000FF593EEB"),"00000000FF593EEB"));
            
            System.out.println(encrypt02("0501"));
            System.out.println(decrypt02(encrypt02("0501")));            
        } 
        catch(Exception e){
        }        
        
     }
}
/*
線上執行: https://www.tutorialspoint.com/compile_java_online.php
Hello World
DRVBtq299GURV29UrfXOpw==
0501
Y5MTre3MWDwP3Zj3+YWgEw==
0501
*/

C#

        //---
        //for php aes128
        //資料來源: https://www.cnblogs.com/bangejingting/p/5600568.html
        //PHP 測試網頁: https://encode-decode.com/aes128-encrypt-online/
        //EX: pin: AES 128加密 範例: 假設密碼為 0501 AES加密的KEY為卡號00000000FF593EEB, 加密後為Y5MTre3MWDwP3Zj3+YWgEw==
        //C# code
        /*
            String data01 = Web_encrypt.AesEncrypt("0501", "00000000FF593EEB");
            String data02 = Web_encrypt.AesDecrypt(data01, "00000000FF593EEB"); 
         */
        public static string AesEncrypt(string str, string key)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);
            Byte[] ivArray = new Byte[16];
            System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(key),
                IV = ivArray,
                Mode = System.Security.Cryptography.CipherMode.ECB,
                Padding = System.Security.Cryptography.PaddingMode.PKCS7,
            };

            System.Security.Cryptography.ICryptoTransform cTransform = rm.CreateEncryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        public static string AesDecrypt(string str, string key)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Convert.FromBase64String(str);
            Byte[] ivArray = new Byte[16];
            System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(key),
                IV = ivArray,
                Mode = System.Security.Cryptography.CipherMode.ECB,
                Padding = System.Security.Cryptography.PaddingMode.PKCS7
            };

            System.Security.Cryptography.ICryptoTransform cTransform = rm.CreateDecryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Encoding.UTF8.GetString(resultArray);
        }
        //---for php aes128

One thought on “java php c# 三種語言的AES加密互轉

  1. C# 在資料這麼短的情況下 CBC 和 ECB 結果會一樣

    但是隨著 資料長度變長,則結果會不同

    目前 在SYRIS公司 PHP 是使用 ECB

    所以特此紀錄

jash.liao@qq.com 發表迴響 取消回覆

你的電子郵件位址並不會被公開。 必要欄位標記為 *