go与java互用的AES实现
终于实现了go与java互用的AES算法实现。基于go可以编译windows与linux下的命令行工具,十分方便。
Java源码
importjava.security.GeneralSecurityException;
importjava.util.Arrays;
importjavax.crypto.Cipher;
importjavax.crypto.spec.IvParameterSpec;
importjavax.crypto.spec.SecretKeySpec;
publicclassAES{
publicstaticbyte[]encrypt(Stringkey,byte[]origData)throwsGeneralSecurityException{
byte[]keyBytes=getKeyBytes(key);
byte[]buf=newbyte[16];
System.arraycopy(keyBytes,0,buf,0,keyBytes.length>buf.length?keyBytes.length:buf.length);
Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE,newSecretKeySpec(buf,"AES"),newIvParameterSpec(keyBytes));
returncipher.doFinal(origData);
}
publicstaticbyte[]decrypt(Stringkey,byte[]crypted)throwsGeneralSecurityException{
byte[]keyBytes=getKeyBytes(key);
byte[]buf=newbyte[16];
System.arraycopy(keyBytes,0,buf,0,keyBytes.length>buf.length?keyBytes.length:buf.length);
Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE,newSecretKeySpec(buf,"AES"),newIvParameterSpec(keyBytes));
returncipher.doFinal(crypted);
}
privatestaticbyte[]getKeyBytes(Stringkey){
byte[]bytes=key.getBytes();
returnbytes.length==16?bytes:Arrays.copyOf(bytes,16);
}
publicstaticStringencrypt(Stringkey,Stringval)throwsGeneralSecurityException{
byte[]origData=val.getBytes();
byte[]crypted=encrypt(key,origData);
returnBase64.Encoder.RFC4648_URLSAFE.encodeToString(crypted);
}
publicstaticStringdecrypt(Stringkey,Stringval)throwsGeneralSecurityException{
byte[]crypted=Base64.Decoder.RFC4648_URLSAFE.decode(val);
byte[]origData=decrypt(key,crypted);
returnnewString(origData);
}
/
@paramargs
@throwsException
/
publicstaticvoidmain(String[]args)throwsException{
if(args.length!=3){
System.err.print("Usage:javaAES(-e|-d)");
}
if("-e".equals(args[0])){
System.out.println(encrypt(args[1],args[2]));
}elseif("-d".equals(args[0])){
System.out.println(decrypt(args[1],args[2]));
}else{
System.err.print("Usage:javaAES(-e|-d)");
}
}
}
Go源码
packagemain
import(
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"os"
)
funcgetKeyBytes(keystring)[]byte{
keyBytes:=[]byte(key)
switchl:=len(keyBytes);{
casel<16:
keyBytes=append(keyBytes,make([]byte,16-l)...)
casel>16:
keyBytes=keyBytes[:16]
}
returnkeyBytes
}
funcencrypt(keystring,origData[]byte)([]byte,error){
keyBytes:=getKeyBytes(key)
block,err:=aes.NewCipher(keyBytes)
iferr!=nil{
returnnil,err
}
blockSize:=block.BlockSize()
origData=PKCS5Padding(origData,blockSize)
blockMode:=cipher.NewCBCEncrypter(block,keyBytes[:blockSize])
crypted:=makewww.baiyuewang.net([]byte,len(origData))
blockMode.CryptBlocks(crypted,origData)
returncrypted,nil
}
funcdecrpt(keystring,crypted[]byte)([]byte,error){
keyBytes:=getKeyBytes(key)
block,err:=aes.NewCipher(keyBytes)
iferr!=nil{
returnnil,err
}
blockSize:=block.BlockSize()
blockMode:=cipher.NewCBCDecrypter(block,keyBytes[:blockSize])
origData:=make([]byte,len(crypted))
blockMode.CryptBlocks(origData,crypted)
origData=PKCS5UnPadding(origData)
returnorigData,nil
}
funcPKCS5Padding(ciphertext[]byte,blockSizeint)[]byte{
padding:=blockSize-len(ciphertext)%blockSize
padtext:=bytes.Repeat([]byte{byte(padding)},padding)
returnappend(ciphertext,padtext...)
}
funcPKCS5UnPadding(origData[]byte)[]byte{
length:=len(origData)
unpadding:=int(origData[length-1])
returnorigData[:(length-unpadding)]
}
funcEncrypt(keystring,valstring)(string,error){
origData:=[]byte(val)
crypted,err:=encrypt(key,origData)
iferr!=nil{
return"",err
}
returnbase64.URLEncoding.EncodeToString(crypted),nil
}
funcDecrypt(keystring,valstring)(string,error){
crypted,err:=base64.URLEncoding.DecodeString(val)
iferr!=nil{
return"",err
}
origData,err:=decrpt(key,crypted)
iferr!=nil{
return"",err
}
returnstring(origData),nil
}
funcmain(){
argc:=len(os.Args)
ifargc!=4{
os.Stdout.WriteString("usage:AES(-e|-d)")
return
}
switchos.Args[1]{
case"-e":
ret,err:=Encrypt(os.Args[2],os.Args[3])
iferr!=nil{
os.Stderr.WriteString(err.Error())
os.Exit(1)
}
println(ret)
case"-d":
ret,err:=Decrypt(os.Args[2],os.Args[3])
iferr!=nil{
os.Stderr.WriteString(err.Error())
os.Exit(1)
}
println(ret)
default:
os.Stdout.WriteString("usage:AES(-e|-d)")
}
}
使用go可以编译Windows与Linux下的可执行工具。
|
|