2014年9月24日 星期三

Create PHP Extension(.so) by using SWIG, for encrypt and decrypt with AES and base32 by using Crypto++(CryptoPP)

Compiling CryptoPP in Visual Studio Reference:
http://programmingknowledgeblog.blogspot.de/2013/04/compiling-and-integrating-crypto-into.html
====================
Key And IV Generator:
====================

#include <string>
#include <iostream>
#include <iomanip>

#include "cryptopp562\osrng.h"

using namespace std;

int main(int argc, char* argv[]){
    // Scratch Area
    const unsigned int BLOCKSIZE = 16 * 8;
    byte pcbScratch[BLOCKSIZE];

    // Random Block
    CryptoPP::AutoSeededRandomPool rng;
    rng.GenerateBlock(pcbScratch, BLOCKSIZE);

    cout << "The generated random block is:" << endl;
    for(unsigned int i = 0; i < BLOCKSIZE; i++){
        cout << "0x" << setbase(16) << std::setw(2) << std::setfill('0');
        cout << static_cast(pcbScratch[i]) << " ";
    }
    cout << endl;
}


===============
CryptoPP.cpp:
===============

#include <iostream>
#include <iomanip>

#include "/usr/include/crypto++/modes.h"
#include "/usr/include/crypto++/aes.h"
#include "/usr/include/crypto++/filters.h"
#include "/usr/include/crypto++/base32.h"

using namespace std;


class aes{
public:
    byte key[32];
    byte iv[CryptoPP::AES::BLOCKSIZE];

    aes(){
        key[0] = 0x1b;    key[1] = 0x2f;    ...    key[30] = 0x75; key[31] = 0x0e;
       
        iv[0] = 0xa9;    iv[1] = 0x86;   ...   iv[14] = 0xc5;    iv[15] = 0x2a;
    }

    string encrypt(string planText){
        string cypherText;

        CryptoPP::CBC_Mode::Encryption Encryptor(key, sizeof(key), iv);

        CryptoPP::StringSource(
            planText,
            true,
            new CryptoPP::StreamTransformationFilter(
                Encryptor,
                new CryptoPP::Base32Encoder(
                    new CryptoPP::StringSink(cypherText)
                )
            )
        );

        return cypherText;
    }

    string decrypt(string cypherText){
        string planText;

        CryptoPP::CBC_Mode::Decryption Decryptor(key, sizeof(key), iv);

        try{
            CryptoPP::StringSource(
                cypherText,
                true,
                new CryptoPP::Base32Decoder(
                    new CryptoPP::StreamTransformationFilter(
                        Decryptor,
                        new CryptoPP::StringSink(planText)
                    )
                )
            );

            return planText;
        }catch(const CryptoPP::Exception& e){
            return e.what();
        }
    }
};

string aesEncrypt(string planText){
    aes advancedEncryptionStandard;
    return advancedEncryptionStandard.encrypt(planText);
}

string aesDecrypt(string cypherText){
    aes advancedEncryptionStandard;
    return advancedEncryptionStandard.decrypt(cypherText);
}


================
SWIG cryptoPP.i
================

%{
#include <iostream>
#include <iomanip>

#include "/usr/include/crypto++/modes.h"
#include "/usr/include/crypto++/aes.h"
#include "/usr/include/crypto++/filters.h"
#include "/usr/include/crypto++/base32.h"

using namespace std;

class aes{
public:
    byte key[32];
    byte iv[CryptoPP::AES::BLOCKSIZE];

    aes(){
        key[0] = 0xeb;    key[1] = 0xda;   ...   key[30] = 0xfb;    key[31] = 0x0f;
       
        iv[0] = 0xa6;    iv[1] = 0x68;    ...   iv[14] = 0xb1;    iv[15] = 0x1d;
    }

    std::string encrypt(std::string planText){
        std::string cypherText;

        CryptoPP::CBC_Mode::Encryption Encryptor(key, sizeof(key), iv);

        CryptoPP::StringSource(
            planText,
            true,
            new CryptoPP::StreamTransformationFilter(
                Encryptor,
                new CryptoPP::Base32Encoder(
                    new CryptoPP::StringSink(cypherText)
                )
            )
        );

        return cypherText;
    }

    std::string decrypt(std::string cypherText){
        std::string planText;

        CryptoPP::CBC_Mode::Decryption Decryptor(key, sizeof(key), iv);

        try{
            CryptoPP::StringSource(
                cypherText,
                true,
                new CryptoPP::Base32Decoder(
                    new CryptoPP::StreamTransformationFilter(
                        Decryptor,
                        new CryptoPP::StringSink(planText)
                    )
                )
            );

            return planText;
        }catch(const CryptoPP::Exception& e){
            return e.what();
        }
    }
};

std::string aesEncrypt(std::string planText){
    aes advancedEncryptionStandard;
    return advancedEncryptionStandard.encrypt(planText);
}

std::string aesDecrypt(std::string cypherText){
    aes advancedEncryptionStandard;
    return advancedEncryptionStandard.decrypt(cypherText);
}
%}


%module cryptoPP
%include "std_string.i"
std::string aesEncrypt(std::string planText);
std::string aesDecrypt(std::string cypherText);


====================
swig -c++ -php5 cryptoPP.i 
g++ `php-config --includes` -O2 -march=native -mtune=native -std=c++11 -lcryptopp -fPIC -c cryptoPP_wrap.cpp

g++ -lcryptopp -shared cryptoPP_wrap.o -o cryptoPP.so 

For preventing from warnings like "PHP Warning: Function registration failed - duplicate name - swig_cryptoPP_alter_newobject, PHP Warning: Function registration failed - duplicate name - swig_cryptoPP_get_newobject", one should load extension in php.ini, for example: extension=cryptoPP.so, instead of dynamic load extension in PHP script with dl() function.

沒有留言:

張貼留言