雜亂大全05-資安與加密的那些事(3):AES實作與應用(對稱密鑰加密)

  • 主題:雜亂大全05-資安與加密的那些事(3):AES實作與應用

  • 前言:接續前幾篇,本篇簡介對稱金鑰加密後將講解AES實際應用情形

  • 叮嚀: $ 代表對CMD或terminal(終端機)下指令

tags: php,encrypt,AES

本篇重點:

  1. 簡介對稱金鑰加密、AES
  2. 實作經驗

對稱金鑰加密

白話來說:就是使用同一把鑰匙進行加密與解密,因此會有如何傳遞金鑰的問題

圖解(引用書本:演算法圖鑑):
image


AES簡介

進階加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。(節錄)

  1. key length(密鑰位數)
  2. key (密鑰)
  3. IV (向量)
  4. mode (加密模式)
  5. padding (填充方式)

實際應用於WebSocket溝通

本次參考與國家地震中心雙方交談時使用的AES加密方式
(均可從網站找到溝通方式)
image

以下提供官方範例文件(使用C#):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


using System;
using System.Security.Cryptography;
using System.Text;


class AESEncrypt
<summary>
加密
</summary>
<param name="text">欲加密的字串</param>
<param name="key">金鑰</param>
<returns></returns>

public static string EncryptAES256(string text, string key)
try
byte[] md5IV = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(key));
byte[] sha256Key = new SHA256CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(key));
byte[] byteContent = Encoding.UTF8.GetBytes(text);

RijndaelManaged aes = new RijndaelManaged();
aes.Key = sha256Key;
aes.IV = md5IV;

aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = aes.CreateEncryptor();

return Convert.ToBase64String(transform.TransformFinalBlock(byteContent, 0, byteContent.Length));

利用上述範例,使用因本專案是使用python
故以下用python進行與官方的websocket溝通

解析整體步驟:

STEP(padding->CBC加密->base64編碼)

  1. key=bytearray(passwd)+text=bytearray(passwd)
  2. RijndaelManaged rijndaelCipher = new
    RijndaelManaged(); (##rijn)
  3. IV=MD5(key)
  4. key=sha256(key)
  5. aes.Mode = CipherMode.CBC;
  6. aes.Padding = PaddingMode.PKCS7;
  7. import base64
    base64.b64encode(bytes(‘your string’, ‘utf-8’))

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from websocket import create_connection
import json
import simplejson as sjson
from Crypto.Cipher import AES
import hashlib
from pkcs7 import PKCS7Encoder
import base64
import time

def AES_encode( key, ID, PW):
Pad_ID = PKCS7Encoder().encode(ID)
Byte_ID = bytes(Pad_ID, 'utf-8')
Pad_PW = PKCS7Encoder().encode(PW)
Byte_PW = bytes(Pad_PW, 'utf-8')
Byte_key = bytes(key, "utf-8")
MD5key = hashlib.md5(Byte_key).digest()
SHAkey = hashlib.sha256(Byte_key).digest()

Encode1 = AES.new(SHAkey, AES.MODE_CBC, MD5key)
Encode2 = AES.new(SHAkey, AES.MODE_CBC, MD5key)
AES_ID = Encode1.encrypt(Byte_ID)
Key_ID = base64.b64encode(AES_ID)
AES_PW = Encode2.encrypt(Byte_PW)
Key_PW = base64.b64encode(AES_PW)

return Key_ID, Key_PW

if _name__=='__main_':
while True:
try:
KeyRequest = {"CMD": "KeyRequest"}
ws =create_connection("#溝通的URL")
ws.send(json.dumps(KeyRequest))
result = ws.recv()
result=json.loads(result)
ID = '#帳號'
PW = '#密碼'
Key = result['Key']
Key_result = AES_encode( Key, ID, PW )
login = {"CMD": "LoginRequest",
"ID": Key_result[0],
"PW": Key_result[1]
}
ws.send(sjson.dumps(login))
result = ws.recv()
#解析回收的資料
#以下是溝通內容,可以省略
result = json.loads(result)
if ( result['MSG'] == "OK"):
while True:
result = ws.recv()
#result = json.loads(result)
print(ws.recv())
time.sleep(1)
except Exception as e:
print (e)
ws.close()
time.sleep(5)
print ("Disconnect")

補充:

因為各個語言C#、PHP、Python
在AES參數寫法上有一些不同,所以文件要寫好
確定好在各參數上都能一致
上述寫法是應雙方文件都使用此類參數


小結語:

AES的使用相較簡單且安全,可以選擇來使用


後續:

下篇將介紹對稱金鑰加密,簡介使用RSA建立加密


參考連結


<追隨前輩們的腳步,不停往前。>

  • 任何問題,請聯繫我:liao86221@gmail.com