zoukankan      html  css  js  c++  java
  • C++ 和 java 使用 AES CBC 128 加解密

    Java 使用jce, code:

    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.util.Arrays;
    
    //import org.apache.commons.codec.binary.Base64;
    
    public class Encryptor {
    
        /**
         * 字符串转换成十六进制字符串
         */
        public static String str2HexStr(String str) {
    
            char[] chars = "0123456789ABCDEF".toCharArray();
            StringBuilder sb = new StringBuilder("");
            byte[] bs = str.getBytes();
            int bit;
            for (int i = 0; i < bs.length; i++) {
                bit = (bs[i] & 0x0f0) >> 4;
                sb.append(chars[bit]);
                bit = bs[i] & 0x0f;
                sb.append(chars[bit]);
            }
            return sb.toString();
        }
    
        /**
         *
         * 十六进制转换字符串
         */
    
        public static byte[] hexStr2Bytes(String hexStr) {
            System.out.println("in len :" + hexStr.length());
            String str = "0123456789ABCDEF";
            char[] hexs = hexStr.toCharArray();
            byte[] bytes = new byte[hexStr.length() / 2];
            int n;
            for (int i = 0; i < bytes.length; i++) {
                n = str.indexOf(hexs[2 * i]) * 16;
                n += str.indexOf(hexs[2 * i + 1]);
                bytes[i] = (byte) (n & 0xff);
            }
            System.out.println("out len :" + bytes.length);
            System.out.println("ddd" + Arrays.toString(bytes));
            return bytes;
        }
    
        /**
         * bytes转换成十六进制字符串
         */
        public static String byte2HexStr(byte[] b) {
            String hs = "";
            String stmp = "";
            for (int n = 0; n < b.length; n++) {
                stmp = (Integer.toHexString(b[n] & 0XFF));
                if (stmp.length() == 1)
                    hs = hs + "0" + stmp;
                else
                    hs = hs + stmp;
                // if (n<b.length-1) hs=hs+":";
            }
            return hs.toUpperCase();
        }
    
        public static String encrypt(String key, String initVector, String value) {
            try {
                System.out.println("key:	" + Arrays.toString(key.getBytes("UTF-8")));
                System.out.println("iv:	" + Arrays.toString(initVector.getBytes("UTF-8")));
                IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
                SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
    
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
                //Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
    
                byte[] encrypted = cipher.doFinal(value.getBytes());
                System.out.println(Arrays.toString(encrypted));
                //System.out.println("encrypted string: "
                //        + Base64.encodeBase64String(encrypted));
    
                return byte2HexStr(encrypted);
                //return Base64.encodeBase64String(encrypted);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        public static String decrypt(String key, String initVector, String encrypted) {
            try {
                IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
                SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
    
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
    
                //byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
                byte[] original = cipher.doFinal(hexStr2Bytes(encrypted));
    
                return new String(original);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        public static void main(String[] args) {
            String key = "1234567890123456"; // 128 bit key
            String initVector = "0000000000000000"; // 16 bytes IV
    
            String en = encrypt(key, initVector, "hello world, cryptopp");
            System.out.println(en);
            System.out.println(decrypt(key, initVector, en));
        }
    }

    编译运行输出

    ➜  cypherTest javac Encryptor.java
    ➜  cypherTest java Encryptor
    key:    [49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54]
    iv:    [48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48]
    [2, -46, -51, -100, 37, -49, 11, 72, -29, -122, -15, -49, -44, -40, -17, -69, -14, -69, -112, -20, -124, 98, -8, 108, -88, 33, 23, 19, -66, 3, -48, -59]
    02D2CD9C25CF0B48E386F1CFD4D8EFBBF2BB90EC8462F86CA8211713BE03D0C5
    in len :64
    out len :32
    ddd[2, -46, -51, -100, 37, -49, 11, 72, -29, -122, -15, -49, -44, -40, -17, -69, -14, -69, -112, -20, -124, 98, -8, 108, -88, 33, 23, 19, -66, 3, -48, -59]
    hello world, cryptopp

    C++ 使用cryptopp库(https://www.cryptopp.com/  下载后,make&& make install 编译安装)

    #ifndef CRYPTOPP_H
    #define CRYPTOPP_H
    
    #include <iostream>
    #include <fstream>
    #include <sstream>
    
    #include <cryptopp/aes.h>
    #include <cryptopp/filters.h>
    #include <cryptopp/modes.h>
    
    
    
    class cryptopp {
    public:
        static bool init(const std::string& key, const std::string& iv);
        static std::string encrypt(const std::string& inputPlainText);
        static std::string decrypt(const std::string& cipherTextHex);
    private:
        static byte s_key[CryptoPP::AES::DEFAULT_KEYLENGTH];
        static byte s_iv[CryptoPP::AES::DEFAULT_KEYLENGTH];
    };
    #endif
    #include "cryptopp.h"
    
    using namespace std;
    
    void print(const string& cipherText) {
        cout << "[";
        for( unsigned int i = 0; i < cipherText.size(); i++ )
        {
            cout << int(cipherText[i]) << ", "  ;
        }
        cout << "]"<< endl;
    }
    
    byte cryptopp::s_key[CryptoPP::AES::DEFAULT_KEYLENGTH];
    byte cryptopp::s_iv[CryptoPP::AES::DEFAULT_KEYLENGTH];
    
    bool cryptopp::init(const string& key, const string& iv) {
        if (key.size() != CryptoPP::AES::DEFAULT_KEYLENGTH) {
            return false;
        }
        if (iv.size() != CryptoPP::AES::BLOCKSIZE) {
            return false;
        }
    
        for(int i = 0; i < CryptoPP::AES::DEFAULT_KEYLENGTH; i++) {
            s_key[i] = key[i];
        }
        for(int i = 0; i < CryptoPP::AES::BLOCKSIZE; i++) {
            s_iv[i] = iv[i];
        }
        //memset(s_key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH);
        //memset(s_iv, 0x00, CryptoPP::AES::BLOCKSIZE);
        return true;
    }
    
    
    
    string cryptopp::encrypt(const string& plainText)
    {
        /*
        if ((plainText.length() % CryptoPP::AES::BLOCKSIZE) != 0) {
            return "";
        }
        */
    
        string cipherTextHex;
        try {
            string cipherText;
            CryptoPP::AES::Encryption aesEncryption(s_key, CryptoPP::AES::DEFAULT_KEYLENGTH);
            CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, s_iv);
            //CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( cipherText ), CryptoPP::StreamTransformationFilter::NO_PADDING);
            CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( cipherText ));
            stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plainText.c_str() ), plainText.length() );
            stfEncryptor.MessageEnd();
    
            print(cipherText);
            for( unsigned int i = 0; i < cipherText.size(); i++ )
            {
                char ch[3] = {0};
                sprintf(ch, "%02x",  static_cast<byte>(cipherText[i]));
                cipherTextHex += ch;
            }
        } catch (const std::exception &e) {
            cipherTextHex = "";
        }
    
        return cipherTextHex;
    }
    
    string cryptopp::decrypt(const string& cipherTextHex)
    {
        /*
        if(cipherTextHex.empty()) {
            return string();
        }
        if ((cipherTextHex.length() % CryptoPP::AES::BLOCKSIZE) != 0) {
            return string();
        }
        */
    
        string cipherText;
        string decryptedText;
    
        unsigned int i = 0;
        while(true)
        {
            char c;
            int x;
            stringstream ss;
            ss<<hex<<cipherTextHex.substr(i, 2).c_str();
            ss>>x;
            c = (char)x;
            cipherText += c;
            if(i >= cipherTextHex.length() - 2)break;
            i += 2;
        }
    
        try {
            CryptoPP::AES::Decryption aesDecryption(s_key, CryptoPP::AES::DEFAULT_KEYLENGTH);
            CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, s_iv );
            //CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedText ),CryptoPP::StreamTransformationFilter::NO_PADDING);
            CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedText ));
            stfDecryptor.Put( reinterpret_cast<const unsigned char*>( cipherText.c_str() ), cipherText.size());
    
            stfDecryptor.MessageEnd();
        } catch (const std::exception &e) {
            decryptedText = "";
        }
    
        return decryptedText;
    }
    
    int main() {
        cryptopp::init("1234567890123456", "0000000000000000");
        string en = cryptopp::encrypt("hello world, cryptopp");
        cout << en << endl;
        cout << cryptopp::decrypt(en) << endl;
    }

    编译 g++ cryptopp.cpp -lcryptopp

    运行输出

    $./a.out
    [2, -46, -51, -100, 37, -49, 11, 72, -29, -122, -15, -49, -44, -40, -17, -69, -14, -69, -112, -20, -124, 98, -8, 108, -88, 33, 23, 19, -66, 3, -48, -59, ]
    02d2cd9c25cf0b48e386f1cfd4d8efbbf2bb90ec8462f86ca8211713be03d0c5
    hello world, cryptopp
  • 相关阅读:
    MySQL性能优化
    mysql中OPTIMIZE TABLE的作用
    Linux中/usr与/var目录详解
    Mysql之EXPLAIN显示using filesort
    MySQL ALTER语法的运用方法 && 操作索引和字段
    NoSQL数据库的分布式算法&&memcache集群的实现
    linux用户权限
    hdoj1241 Oil Deposits
    ny42 一笔画问题
    ny20 吝啬的国度
  • 原文地址:https://www.cnblogs.com/diegodu/p/6273611.html
Copyright © 2011-2022 走看看