[加解密]js/python/golang 相容AES(CBC/ECB)加解密(1)--ECB模式
起因是想實現oracle相容的加解密演算法,結果折騰了好幾天也沒有搞定相容的3des演算法.
副產品是把aes的各種場景驗證了一遍.
之前沒有密碼學基礎,通過折騰,稍微瞭解了一點.AES是比3des更先進的加密演算法,雖然現在也不可靠了.
加密的塊處理模式分為ECB和CBC. ECB因為不安全,已經廢棄.如果不考慮和php相容,那麼可以不用了.
塊處理就涉及一個填充模式,常見的填充模式,有補0(ZeroPadding)和補位數(PKcs5/PKcs7)
AES的相容性相對比較好.可以先線上測試一下,獲得比較基準.http://tool.chacuo.net/cryptaes
下面分別上程式碼(差別不大,但是分開來看得比較清楚)
先來ECB的,雖然已經淘汰了, 網上搜索的很多反而是這個.
js的,需要下載CrypoJS庫. 注意解密的是base格式的str.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <script src="rollups/aes.js"></script> <script src="components/pad-zeropadding.js"></script> <script src="components/mode-ecb.js"></script> <body> <script> var key = CryptoJS.enc.Utf8.parse("abcdefgh12345678"); var plaintText = 'www.baidu.com'; // 明文 //var plaintText = 'www.baidu.com'; // 明文 var encryptedData = CryptoJS.AES.encrypt(plaintText, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 //padding: CryptoJS.pad.ZeroPadding }); console.log("加密前:"+plaintText); console.log("加密後:"+encryptedData); encryptedData = encryptedData.ciphertext.toString(); var encryptedHexStr = CryptoJS.enc.Hex.parse(encryptedData); console.log("解密前hex:"+encryptedHexStr); var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr); console.log("解密前:"+encryptedBase64Str); var decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); var decryptedStr = decryptedData.toString(CryptoJS.enc.Utf8); console.log("解密後:"+decryptedStr); </script> </body> </html>
golang的. 比較囉嗦.封裝層次太低,padding函式也要自己寫.
/* 描述 : golang AES/ECB/PKCS5|Zero 加密解密 date : 2016-04-08 */ package main import ( "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" "fmt" "strings" ) func main() { /* *src 要加密的字串 *key 用來加密的金鑰 金鑰長度可以是128bit、192bit、256bit中的任意一個 *16位key對應128bit */ src := "www.baidu.com" key := "abcdefgh12345678" crypted := AesEncrypt(src, key) AesDecrypt(crypted, []byte(key)) } func AesDecrypt(crypted, key []byte) []byte { block, err := aes.NewCipher(key) if err != nil { fmt.Println("err is:", err) } blockMode := NewECBDecrypter(block) origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) //origData = PKCS5UnPadding(origData) origData = ZeroUnPadding(origData) fmt.Println("source is :", origData, string(origData)) return origData } func AesEncrypt(src, key string) []byte { block, err := aes.NewCipher([]byte(key)) if err != nil { fmt.Println("key error1", err) } if src == "" { fmt.Println("plain content empty") } ecb := NewECBEncrypter(block) content := []byte(src) //content = PKCS5Padding(content, block.BlockSize()) content = ZeroPadding(content, block.BlockSize()) crypted := make([]byte, len(content)) ecb.CryptBlocks(crypted, content) fmt.Println("base64 result:", base64.StdEncoding.EncodeToString(crypted)) return crypted } func PKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize//需要padding的數目 //只要少於256就能放到一個byte中,預設的blockSize=16(即採用16*8=128, AES-128長的金鑰) //最少填充1個byte,如果原文剛好是blocksize的整數倍,則再填充一個blocksize padtext := bytes.Repeat([]byte{byte(padding)}, padding)//生成填充的文字 return append(ciphertext, padtext...) } func PKCS5UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } func ZeroPadding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{0}, padding)//用0去填充 return append(ciphertext, padtext...) } func ZeroUnPadding(origData []byte) []byte { return bytes.TrimFunc(origData, func(r rune) bool { return r == rune(0) }) } type ecb struct { b cipher.Block blockSize int } func newECB(b cipher.Block) *ecb { return &ecb{ b: b, blockSize: b.BlockSize(), } } type ecbEncrypter ecb // NewECBEncrypter returns a BlockMode which encrypts in electronic code book // mode, using the given Block. func NewECBEncrypter(b cipher.Block) cipher.BlockMode { return (*ecbEncrypter)(newECB(b)) } func (x *ecbEncrypter) BlockSize() int { return x.blockSize } func (x *ecbEncrypter) CryptBlocks(dst, src []byte) { if len(src)%x.blockSize != 0 { panic("crypto/cipher: input not full blocks") } if len(dst) < len(src) { panic("crypto/cipher: output smaller than input") } for len(src) > 0 { x.b.Encrypt(dst, src[:x.blockSize]) src = src[x.blockSize:] dst = dst[x.blockSize:] } } type ecbDecrypter ecb // NewECBDecrypter returns a BlockMode which decrypts in electronic code book // mode, using the given Block. func NewECBDecrypter(b cipher.Block) cipher.BlockMode { return (*ecbDecrypter)(newECB(b)) } func (x *ecbDecrypter) BlockSize() int { return x.blockSize } func (x *ecbDecrypter) CryptBlocks(dst, src []byte) { if len(src)%x.blockSize != 0 { panic("crypto/cipher: input not full blocks") } if len(dst) < len(src) { panic("crypto/cipher: output smaller than input") } for len(src) > 0 { x.b.Decrypt(dst, src[:x.blockSize]) src = src[x.blockSize:] dst = dst[x.blockSize:] } }
python的. 還行.不過加解密的物件是byte
#coding=utf-8
#AES-demo AES/ECB/PKCS5|Zero
#ECB不安全.建議CBC
import base64
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
def ByteToHex( bins ):
"""
Convert a byte string to it's hex string representation e.g. for output.
"""
return ''.join( [ "%02X" % x for x in bins ] ).strip()
'''
採用AES對稱加密演算法
'''
# str不是16的倍數那就補足為16的倍數. ZeroPadding
'''
在PKCS5Padding中,明確定義Block的大小是8位
而在PKCS7Padding定義中,對於塊的大小是不確定的,可以在1-255之間
PKCS #7 填充字串由一個位元組序列組成,每個位元組填充該位元組序列的長度。
假定塊長度為 8,資料長度為 9,
資料: FF FF FF FF FF FF FF FF FF
PKCS7 填充: FF FF FF FF FF FF FF FF FF 01 01 01 01 01 01 01 ?應該是填充01
python3:填充bytes(這個說法不對,AES的引數是字串,不是byte)
length = 16 - (len(data) % 16)
data += bytes([length])*length
python2:填充字串
length = 16 - (len(data) % 16)
data += chr(length)*length
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]
'''
def add_to_16(value):
while len(value) % 16 != 0:
value += '\0'
return str.encode(value) # 返回bytes
def ZeroPadding(value,bs):
while len(value) % bs != 0:
value += '\0'
return str.encode(value) # 返回bytes
def PKCS7Padding(value,bs):
pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)#PKS7
return str.encode(pad(value)) # 返回bytes
def PKCS7UnPadding(value):
#value = value[:-value[-1]]
unpad = lambda s : s[0:-ord(s[-1])] #獲得資料的長度,擷取
return unpad(value)
#加密方法
def encrypt_oracle():
# 祕鑰
key = 'abcdefgh12345678'
# 待加密文字
text = 'www.baidu.com'
# 初始化加密器
aes = AES.new(add_to_16(key), AES.MODE_ECB)
bs = AES.block_size
pad2 = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)#PKS7 就是pkcs7padding
#先進行aes加密
#Zeropadding
#encrypt_aes = aes.encrypt(add_to_16(text))
#Pkcs7 padding
encrypt_aes = aes.encrypt(str.encode(pad2(text)))
#轉為hex
print(ByteToHex(encrypt_aes)) #轉為字串
print(b2a_hex(encrypt_aes)) #b''
#用base64轉成字串形式
encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') # 執行加密並轉碼返回bytes
print(encrypted_text)
#和js的 結果相同 http://tool.chacuo.net/cryptaes
return encrypted_text
#解密方法
def decrypt_oralce(text):
# 祕鑰
key = 'abcdefgh12345678'
# 密文
# 初始化加密器
aes = AES.new(add_to_16(key), AES.MODE_ECB)
#優先逆向解密base64成bytes
base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8'))
#
decrypted_text = str(aes.decrypt(base64_decrypted),encoding='utf-8') # 執行解密密並轉碼返回str
unpad = lambda s : s[0:-ord(s[-1])] #pkcs7unpadding比較簡單.
print(unpad(decrypted_text))
if __name__ == '__main__':
en=encrypt_oracle()
decrypt_oralce(en)
相關推薦
[加解密]js/python/golang 相容AES(CBC/ECB)加解密(1)--ECB模式
起因是想實現oracle相容的加解密演算法,結果折騰了好幾天也沒有搞定相容的3des演算法. 副產品是把aes的各種場景驗證了一遍. 之前沒有密碼學基礎,通過折騰,稍微瞭解了一點.AES是比3des更先進的加密演算法,雖然現在也不可靠了. 加密的塊處理模式分為ECB
[加解密]js/python/golang 相容AES(CBC/ECB)加解密(2)--CBC模式
CBC模式用起來差別不大,就是多了一個iv還是先來js的<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <tit
golang實現aes-cbc-256加密解密過程記錄
generic 返回 hint pie follow strong pri hms 加密解密 我為什麽吃撐了要實現go的aes-cbc-256加密解密功能? 之前的項目是用php實現的,現在準備用go重構,需要用到這個功能,這麽常用的功能上網一搜一大把現成例子,於是基於g
golang使用aes庫實現加解密
golang實現加密解密的庫很多, 這裡使用的是aes庫+base64庫來實現. 使用時,需要指定一個私鑰,來進行加解密, 這裡指定是: var aeskey = []byte(“321423u9y
手機號的 AES/CBC/PKCS7Padding 加解密
.sh cipher 字節 padding name key inf ret def 前言:接口中上次的手機號碼和密碼是傳入的加密的,模擬自動化的時候也需要先對數據進行加密 代碼操作 # coding=utf-8 import hashlib from Cr
Golang實現AES/CBC/PKCS5Padding演算法
使用golang實現AES演算法很簡單,系統庫中已自帶了CBC、CFB等等許多加密模式,而且可以很方便的設定IVPara,但是前幾日在做AES加密時,發現傳入的key必須是128bit、192bit或256bit,記得當時用Java實現的時候並沒有這個問題。AES中的key的
angularjs ocLazyLoad分步加載js文件,angularjs ocLazyLoad按需加載js
path 技術分享 active meta 代碼 效果 function 初始化 reat 用angular有一段時間了,平日裏只顧著寫代碼,沒有註意到性能優化的問題,而今有時間,於是捋了捋,講學習過程記錄於此: 問題描述:由於采用angular做了網頁的單頁面應用,
AES-128-CBC-PKCS5PADDING 加解密實現
Copyright © 2018 Joyce_BY, all rights reserved. Contact by email: [email protected] 本文目的及實驗環境 1、實現128-bit的AES加解密過程 2、python3.7.0,windo
aes/cbc/pkcs5padding/128加解密
//******aes/cbc/pkcs5padding/128加解密****** private function aesEncrypt($data,$iv=''){ $enc_key = 'KlW';//隨機生成16為由大小寫字元和數字組成的字串
JAVA AES文件加解密
輸出 byte stat spa urn code for cat substring AES加解密算法,代碼如下: /** * Created by hua on 2017/6/30. */ import javax.crypto.Cipher; import j
用python給html裏的css及js文件鏈接自動添加版本號
odin link 鏈接 寫入 dir bsp gulp () pan 傳統的給文件鏈接添加版本號的方法是使用gulp-rev,這裏提出的解決方案是使用python來替代gulp-rev。 import os import re import uuid impor
python AES CBC模式加密
理解 定義 代碼 Coding imp lai encrypted python .net 今天需要用到AES CBC模式加密,搜索了很久,終於加密成功,記錄一下今天的理解。 首先要安裝pycrypto庫,不知道為什麽在windows安裝失敗,在linux可以正常安裝 ht
Python3 學習加解密 系列 4 --Cryptodome -Cipher-AES
由於Crypto 安裝 麻煩,選擇了和它一樣專案的Cryptodome包 直接 pip install pycryptodome 就行 先help 發現 有多種加密方式: 看 Cryptodome 原始碼 有很多功能 先看第一個AES: 瞭解下 AES的加密模式:https://
PHP AES cbc模式 pkcs7 128加密解密
今天在對接一個第三方介面的時候,對方需要AES CBC模式下的加密。這裡簡單寫一個demo class Model_Junjingbao extends Model { private static $_partnerKey = '6d70a09e4d0f8095'; //
java實現AES&MD5加解密
AES: import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.bin
python AES-16位加密解密功能實現
從網上搜了很多這種python AES相關內容,但是大部分都是需要自己除錯修改半天才能使用,有的甚至埋下很多坑,費時費力,我這邊根據專案需求,也需要弄一套AES-16位加密和解密API 我用的python加密元件是Crypto,很好用,可以從網上下載最新的庫,我用的比較穩
AES CBC加密/解密
簡介 高階加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高
JAVA 實現對稱解密小程式使用者資訊(AES-128-CBC演算法)
需要引入bcprov.jar包 <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</ar
JS AES加密與PHP解密
網頁端(在沒有https情況下)給密碼之類的加密傳輸,雖然多此一舉,也好過直接監控軟體就能看到密碼 思路 在傳輸密碼的時候,先向後臺獲取一個隨機碼或者驗證碼,作為祕鑰,網頁端根據這個祕鑰,加密要傳輸的資料,服務端先驗證驗證碼是否正確,如果驗證正確,根據驗
PHP和Java AES 128 ECB 加解密(PKCS5Padding)
php 和 java 使用 AES128/ECB/PKCS5Padding對稱加解密,簽名使用 HmacSHA256,附帶 php 和 java 程式碼,均為 DEMO 版本,測試通過,實際使用請根據自己專案修改。 最近做專案涉及到一丟丟的安全問題,需