美文网首页Android 干货androidAndroid NDK
ubuntu移植crypto++到Android平台

ubuntu移植crypto++到Android平台

作者: Andy周 | 来源:发表于2016-08-08 23:52 被阅读482次

    ubuntu移植crypto++到Android平台
    官方Wiki
    http://www.cryptopp.com/wiki/Android_(Command_Line)
    这个移植比较简单,官方直接就有文档了,而且有现成的脚本。
    setenv-android.sh

    #!/usr/bin/env bash
    
    # ====================================================================
    # Sets the cross compile environment for Android
    # Based upon OpenSSL's setenv-android.sh (by TH, JW, and SM).
    #
    # Crypto++ Library is copyrighted as a compilation and (as of version 5.6.2)
    # licensed under the Boost Software License 1.0, while the individual files
    # in the compilation are all public domain.
    #
    # See http://www.cryptopp.com/wiki/Android_(Command_Line) for more details
    # ====================================================================
    
    unset IS_CROSS_COMPILE
    
    unset IS_IOS
    unset IS_ANDROID
    unset IS_ARM_EMBEDDED
    
    unset AOSP_FLAGS
    unset AOSP_SYSROOT
    unset AOSP_STL_INC
    unset AOSP_STL_LIB
    unset AOSP_BITS_INC
    
    # Set AOSP_TOOLCHAIN_SUFFIX to your preference of tools and STL library.
    #   Note: 4.9 is required for the latest architectures, like ARM64/AARCH64.
    # AOSP_TOOLCHAIN_SUFFIX=4.8
    # AOSP_TOOLCHAIN_SUFFIX=4.9
    if [ -z "$AOSP_TOOLCHAIN_SUFFIX" ]; then
        AOSP_TOOLCHAIN_SUFFIX=4.9
    fi
    
    # Set AOSP_API to the API you want to use. 'armeabi' and 'armeabi-v7a' need
    #   API 3 (or above), 'mips' and 'x86' need API 9 (or above), etc.
    # AOSP_API="android-3"     # Android 1.5 and above
    # AOSP_API="android-4"     # Android 1.6 and above
    # AOSP_API="android-5"     # Android 2.0 and above
    # AOSP_API="android-8"     # Android 2.2 and above
    # AOSP_API="android-9"     # Android 2.3 and above
    # AOSP_API="android-14"    # Android 4.0 and above
    # AOSP_API="android-18"    # Android 4.3 and above
    # AOSP_API="android-19"    # Android 4.4 and above
    # AOSP_API="android-21"    # Android 5.0 and above
    # AOSP_API="android-23"    # Android 6.0 and above
    if [ -z "$AOSP_API" ]; then
        AOSP_API="android-21"
    fi
    
    #####################################################################
    
    # ANDROID_NDK_ROOT should always be set by the user (even when not running this script)
    #   http://groups.google.com/group/android-ndk/browse_thread/thread/a998e139aca71d77.
    # If the user did not specify the NDK location, try and pick it up. We expect something
    #   like ANDROID_NDK_ROOT=/opt/android-ndk-r10e or ANDROID_NDK_ROOT=/usr/local/android-ndk-r10e.
    
    export ANDROID_NDK_ROOT=/workspace/android-ndk-r10e
    
    if [ -z "$ANDROID_NDK_ROOT" ]; then
        ANDROID_NDK_ROOT=$(find /opt -maxdepth 1 -type d -name android-ndk-r10* 2>/dev/null | tail -1)
    
        if [ -z "$ANDROID_NDK_ROOT" ]; then
            ANDROID_NDK_ROOT=$(find /usr/local -maxdepth 1 -type d -name android-ndk-r10* 2>/dev/null | tail -1)
        fi
        if [ -z "$ANDROID_NDK_ROOT" ]; then
            ANDROID_NDK_ROOT=$(find $HOME -maxdepth 1 -type d -name android-ndk-r10* 2>/dev/null | tail -1)
        fi
    fi
    
    # Error checking
    if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; then
        echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    #####################################################################
    
    if [ "$#" -lt 1 ]; then
        THE_ARCH=armv7
    else
        THE_ARCH=$(tr [A-Z] [a-z] <<< "$1")
    fi
    
    # https://developer.android.com/ndk/guides/abis.html
    case "$THE_ARCH" in
      arm|armv5|armv6|armv7|armeabi)
        TOOLCHAIN_BASE="arm-linux-androideabi"
        TOOLNAME_BASE="arm-linux-androideabi"
        AOSP_ABI="armeabi"
        AOSP_ARCH="arch-arm"
        AOSP_FLAGS="-march=armv5te -mtune=xscale -mthumb -msoft-float -funwind-tables -fexceptions -frtti"
        ;;
      armv7a|armeabi-v7a)
        TOOLCHAIN_BASE="arm-linux-androideabi"
        TOOLNAME_BASE="arm-linux-androideabi"
        AOSP_ABI="armeabi-v7a"
        AOSP_ARCH="arch-arm"
        AOSP_FLAGS="-march=armv7-a -mthumb -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8 -funwind-tables -fexceptions -frtti"
        ;;
      hard|armv7a-hard|armeabi-v7a-hard)
        TOOLCHAIN_BASE="arm-linux-androideabi"
        TOOLNAME_BASE="arm-linux-androideabi"
        AOSP_ABI="armeabi-v7a"
        AOSP_ARCH="arch-arm"
        AOSP_FLAGS="-mhard-float -D_NDK_MATH_NO_SOFTFP=1 -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8 -funwind-tables -fexceptions -frtti -Wl,--no-warn-mismatch -Wl,-lm_hard"
        ;;
      neon|armv7a-neon)
        TOOLCHAIN_BASE="arm-linux-androideabi"
        TOOLNAME_BASE="arm-linux-androideabi"
        AOSP_ABI="armeabi-v7a"
        AOSP_ARCH="arch-arm"
        AOSP_FLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8 -funwind-tables -fexceptions -frtti"
        ;;
      armv8|armv8a|aarch64|arm64|arm64-v8a)
        TOOLCHAIN_BASE="aarch64-linux-android"
        TOOLNAME_BASE="aarch64-linux-android"
        AOSP_ABI="arm64-v8a"
        AOSP_ARCH="arch-arm64"
        AOSP_FLAGS="-funwind-tables -fexceptions -frtti"
        ;;
      mips|mipsel)
        TOOLCHAIN_BASE="mipsel-linux-android"
        TOOLNAME_BASE="mipsel-linux-android"
        AOSP_ABI="mips"
        AOSP_ARCH="arch-mips"
        AOSP_FLAGS="-funwind-tables -fexceptions -frtti"
        ;;
      mips64|mipsel64|mips64el)
        TOOLCHAIN_BASE="mips64el-linux-android"
        TOOLNAME_BASE="mips64el-linux-android"
        AOSP_ABI="mips64"
        AOSP_ARCH="arch-mips64"
        AOSP_FLAGS="-funwind-tables -fexceptions -frtti"
        ;;
      x86)
        TOOLCHAIN_BASE="x86"
        TOOLNAME_BASE="i686-linux-android"
        AOSP_ABI="x86"
        AOSP_ARCH="arch-x86"
        AOSP_FLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions -frtti"
        ;;
      x86_64|x64)
        TOOLCHAIN_BASE="x86_64"
        TOOLNAME_BASE="x86_64-linux-android"
        AOSP_ABI="x86_64"
        AOSP_ARCH="arch-x86_64"
        AOSP_FLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions -frtti"
        ;;
      *)
        echo "ERROR: Unknown architecture $1"
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
        ;;
    esac
    
    #####################################################################
    
    # GNUmakefile-cross expects these to be set. They are also used in the tests below.
    export IS_ANDROID=1
    export AOSP_FLAGS
    
    # TODO: for the previous GNUmakefile-cross. These can go away eventually.
    export ANDROID_FLAGS=$AOSP_FLAGS
    
    export CPP="$TOOLNAME_BASE-cpp"
    export CC="$TOOLNAME_BASE-gcc"
    export CXX="$TOOLNAME_BASE-g++"
    export LD="$TOOLNAME_BASE-ld"
    export AS="$TOOLNAME_BASE-as"
    export AR="$TOOLNAME_BASE-ar"
    export RANLIB="$TOOLNAME_BASE-ranlib"
    export STRIP="$TOOLNAME_BASE-strip"
    
    #####################################################################
    
    # Based on ANDROID_NDK_ROOT, try and pick up the path for the tools. We expect something
    # like /opt/android-ndk-r10e/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86_64/bin
    # Once we locate the tools, we add it to the PATH.
    AOSP_TOOLCHAIN_PATH=""
    for host in "linux-x86_64" "darwin-x86_64" "linux-x86" "darwin-x86"
    do
        if [ -d "$ANDROID_NDK_ROOT/toolchains/$TOOLCHAIN_BASE-$AOSP_TOOLCHAIN_SUFFIX/prebuilt/$host/bin" ]; then
            AOSP_TOOLCHAIN_PATH="$ANDROID_NDK_ROOT/toolchains/$TOOLCHAIN_BASE-$AOSP_TOOLCHAIN_SUFFIX/prebuilt/$host/bin"
            break
        fi
    done
    
    # Error checking
    if [ -z "$AOSP_TOOLCHAIN_PATH" ] || [ ! -d "$AOSP_TOOLCHAIN_PATH" ]; then
        echo "ERROR: AOSP_TOOLCHAIN_PATH is not valid. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Error checking
    if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CPP" ]; then
        echo "ERROR: Failed to find Android cpp. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Error checking
    if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CC" ]; then
        echo "ERROR: Failed to find Android gcc. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CXX" ]; then
        echo "ERROR: Failed to find Android g++. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Error checking
    if [ ! -e "$AOSP_TOOLCHAIN_PATH/$RANLIB" ]; then
        echo "ERROR: Failed to find Android ranlib. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Error checking
    if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AR" ]; then
        echo "ERROR: Failed to find Android ar. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Error checking
    if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AS" ]; then
        echo "ERROR: Failed to find Android as. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Error checking
    if [ ! -e "$AOSP_TOOLCHAIN_PATH/$LD" ]; then
        echo "ERROR: Failed to find Android ld. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Only modify/export PATH if AOSP_TOOLCHAIN_PATH good
    if [ -d "$AOSP_TOOLCHAIN_PATH" ]; then
    
        # And only modify PATH if AOSP_TOOLCHAIN_PATH is not present
        LEN=${#AOSP_TOOLCHAIN_PATH}
        SUBSTR=${PATH:0:$LEN}
        if [ "$SUBSTR" != "$AOSP_TOOLCHAIN_PATH" ]; then
            export PATH="$AOSP_TOOLCHAIN_PATH":"$PATH"
        fi
    fi
    
    #####################################################################
    
    # Error checking
    if [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API" ]; then
        echo "ERROR: AOSP_API is not valid. Does the NDK support the API? Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    elif [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH" ]; then
        echo "ERROR: AOSP_ARCH is not valid. Does the NDK support the architecture? Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Android SYSROOT. It will be used on the command line with --sysroot
    #   http://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html
    export AOSP_SYSROOT="$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH"
    
    # TODO: export for the previous GNUmakefile-cross. These can go away eventually.
    export ANDROID_SYSROOT=$AOSP_SYSROOT
    
    #####################################################################
    
    # Android STL. We support GNU, LLVM and STLport out of the box.
    
    if [ "$#" -lt 2 ]; then
        THE_STL=stlport-shared
    else
        THE_STL=$(tr [A-Z] [a-z] <<< "$2")
    fi
    
    case "$THE_STL" in
      stlport-static)
        AOSP_STL_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/stlport/"
        AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/libs/$AOSP_ABI/libstlport_static.a"
        ;;
      stlport|stlport-shared)
        AOSP_STL_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/stlport/"
        AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/libs/$AOSP_ABI/libstlport_shared.so"
        ;;
      gabi++-static|gnu-static)
        AOSP_STL_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$AOSP_TOOLCHAIN_SUFFIX/include"
        AOSP_BITS_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$AOSP_TOOLCHAIN_SUFFIX/libs/$AOSP_ABI/include"
        AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$AOSP_TOOLCHAIN_SUFFIX/libs/$AOSP_ABI/libgnustl_static.a"
        ;;
      gnu|gabi++|gnu-shared|gabi++-shared)
        AOSP_STL_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$AOSP_TOOLCHAIN_SUFFIX/include"
        AOSP_BITS_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$AOSP_TOOLCHAIN_SUFFIX/libs/$AOSP_ABI/include"
        AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$AOSP_TOOLCHAIN_SUFFIX/libs/$AOSP_ABI/libgnustl_shared.so"
        ;;
      llvm-static)
        AOSP_STL_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libcxx/include"
        AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_static.a"
        ;;
      llvm|llvm-shared)
        AOSP_STL_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libcxx/include"
        AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_shared.so"
        ;;
      *)
        echo "ERROR: Unknown STL library $2"
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    esac
    
    # Error checking
    if [ ! -d "$AOSP_STL_INC" ] || [ ! -e "$AOSP_STL_INC/memory" ]; then
        echo "ERROR: AOSP_STL_INC is not valid. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    # Error checking
    if [ ! -e "$AOSP_STL_LIB" ]; then
        echo "ERROR: AOSP_STL_LIB is not valid. Please edit this script."
        [ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
    fi
    
    export AOSP_STL_INC
    export AOSP_STL_LIB
    
    # TODO: for the previous GNUmakefile-cross. These can go away eventually.
    export ANDROID_STL_INC=$AOSP_STL_INC
    export ANDROID_STL_LIB=$AOSP_STL_LIB
    
    if [ ! -z "$AOSP_BITS_INC" ]; then
        export AOSP_BITS_INC
    fi
    
    #####################################################################
    
    VERBOSE=1
    if [ ! -z "$VERBOSE" ] && [ "$VERBOSE" != "0" ]; then
      echo "ANDROID_NDK_ROOT: $ANDROID_NDK_ROOT"
      echo "AOSP_TOOLCHAIN_PATH: $AOSP_TOOLCHAIN_PATH"
      echo "AOSP_ABI: $AOSP_ABI"  
      echo "AOSP_API: $AOSP_API"
      echo "AOSP_SYSROOT: $AOSP_SYSROOT"
      echo "AOSP_FLAGS: $AOSP_FLAGS"
      echo "AOSP_STL_INC: $AOSP_STL_INC"
      echo "AOSP_STL_LIB: $AOSP_STL_LIB"
      if [ ! -z "$AOSP_BITS_INC" ]; then
        echo "AOSP_BITS_INC: $AOSP_BITS_INC"
      fi
    fi
    
    [ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0
    

    将ANDROID_NDK_ROOT改成自己本机上的
    有两个参数

    armeabi
    armeabi-v7a
    armeabi-v7a-hard
    arm64-v8a
    mips
    mips64
    x86
    x86_64
    

    第二个参数

    stlport (shared)
    stlport-static
    stlport-shared
    gnu (shared)
    gnu-static
    gnu-shared
    

    生成动态库和静态库

    make -f GNUmakefile-cross static dynamic
    

    最后官方的脚本
    build-all-android.sh

    #!/bin/bash
    
    for arch in armeabi armeabi-v7a armeabi-v7a-hard arm64-v8a mips mips64 x86 x86_64
    do
        . ./setenv-android.sh $arch stlport
        if [ "$?" -eq "0" ]; then
            make -f GNUmakefile-cross distclean
            make -f GNUmakefile-cross static dynamic
            sudo make -f GNUmakefile-cross install PREFIX=/usr/local/cryptopp/android-$arch
        fi
    done
    

    直接编译生成即可
    在/usr/local/cryptopp

    测试一下

    新建JNI目录
    将libcryptopp.a和include目录复制进去
    新建Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := cryptopp  
    LOCAL_SRC_FILES := libcryptopp.a
    include $(PREBUILT_STATIC_LIBRARY)  
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := main
    LOCAL_C_INCLUDES  := $(LOCAL_PATH)/include
    LOCAL_SRC_FILES := main.cpp
    LOCAL_CPPFLAGS := -fexceptions
    LOCAL_STATIC_LIBRARIES := cryptopp
    
    LOCAL_CFLAGS += -pie -fPIE
    LOCAL_LDFLAGS += -pie -fPIE
    
    include $(BUILD_EXECUTABLE)
    

    新建Application.mk

    APP_ABI := armeabi
    APP_PLATFORM := 12
    APP_CPPFLAGS += -fexceptions -frtti
    APP_STL := stlport_static
    

    新建源代码文件main.cpp

    #include <cryptopp/randpool.h>   
    #include <cryptopp/rsa.h>   
    #include <cryptopp/hex.h>  
    #include <cryptopp/files.h>   
    #include <iostream>   
      
    using namespace std;   
    using namespace CryptoPP;   
    
    //------------------------   
    // 函数声明  
    //------------------------   
    void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);   
    string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);   
    string RSADecryptString(const char *privFilename, const char *ciphertext);   
    RandomPool & GlobalRNG();   
      
    //------------------------   
    // 主程序  
    //------------------------   
    int main()   
    {   
        char priKey[128] = {0};   
        char pubKey[128] = {0};   
        char seed[1024] = {0};   
      
        // 生成 RSA 密钥对  
        strcpy(priKey, "pri"); // 生成的私钥文件  
        strcpy(pubKey, "pub"); // 生成的公钥文件  
        strcpy(seed, "seed");   
        GenerateRSAKey(1024, priKey, pubKey, seed);   
      
        //RSA 加解密  
        char message[1024] = "Hello World ...";   
        cout<<"Origin Text:\t"<< message <<endl<<endl;     
        string encryptedText = RSAEncryptString(pubKey, seed, message); // RSA 加密  
        cout<<"Encrypted Text:\t"<<encryptedText<<endl<<endl;   
        string decryptedText = RSADecryptString(priKey, encryptedText.c_str()); // RSA  解密  
        cout<<"Decrypted Text:\t"<<decryptedText<<endl<<endl;   
          
        return 0;  
    }   
      
    //------------------------   
    //生成 RSA 密钥对  
    //------------------------   
    void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)   
    {   
           RandomPool randPool;   
           randPool.Put((byte *)seed, strlen(seed));   
      
           RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);   
           HexEncoder privFile(new FileSink(privFilename));   
           priv.DEREncode(privFile);   
           privFile.MessageEnd();   
      
           RSAES_OAEP_SHA_Encryptor pub(priv);   
           HexEncoder pubFile(new FileSink(pubFilename));   
           pub.DEREncode(pubFile);   
           pubFile.MessageEnd();   
    }   
    //------------------------   
    // RSA 加密  
    //------------------------   
    string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)  
    {  
           FileSource pubFile(pubFilename, true, new HexDecoder);  
           RSAES_OAEP_SHA_Encryptor pub(pubFile);  
      
           RandomPool randPool;  
           randPool.Put((byte *)seed, strlen(seed));  
      
           string result;  
           StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));  
           return result;  
    }  
      
    //------------------------   
    // RSA  解密  
    //------------------------   
    string RSADecryptString(const char *privFilename, const char *ciphertext)  
    {  
           FileSource privFile(privFilename, true, new HexDecoder);  
           RSAES_OAEP_SHA_Decryptor priv(privFile);  
      
           string result;  
           StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));  
           return result;  
      
    }  
      
    //------------------------   
    // 定义全局的随机数池  
    //------------------------   
    RandomPool & GlobalRNG()  
    {  
           static RandomPool randomPool;  
           return randomPool;  
    }  
    

    接着编译

    ndk-build
    

    将生成的main文件push到手机内,运行

    相关文章

      网友评论

        本文标题:ubuntu移植crypto++到Android平台

        本文链接:https://www.haomeiwen.com/subject/rjsrsttx.html