رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران

پست های پیشنهاد شده

همواره یکی از چالش بر انگیزترین مباحث در دنیای نرم افزار حفاظت از داده های حساس برنامه ها می باشد.

البته امروزه با کتابخانه ها و الگوریتم های رمزنگاری موجود در این صنعت کمی از عذاب آورترین چالش های مهندسین نرم افزار کمتر شده است، ولی به هرحال تمامی این روشها جدایی از بحث انعطاف پذیری و اطمینان از صحت اجرای الگوریتم توانایی اجرا در همه سکوها را ندارند.

با این مقدمه کوتاه به بحث پر چالش ترین زبان برنامه نویسی جاوا و البته سیستم عامل معروف اندروید تحت این سکو می پردازیم، همانطور که می دانید حفاظت از داده های حساس در اندروید به علت متن باز بودن سکوی خود می تواند یکی از پر چالش ترین بحث های برنامه نویسی باشد. به همین علت کتابخانه ها و روش های زیادی وجود دارند تا از این اطلاعات حساس نگهداری نمایید.

البته در این مقاله بحث بر سرحفاظت از اطلاعات حساس در زمان اجرای اپ های موبایل می باشد مانند کلمات عبور و یا اطلاعات حساس استفاده شده در وب سرویس ها در زمان ارسال پکت ها به سرور می باشد. بنابراین در اینجا کاری با قسمت پایگاه داده و روش های برنامه نویسی سوکت و مباحث دیگر نخواهیم داشت.

در زبان جاوای گوگل که برای سیستم عامل اندروید توسعه داده شده است ابزار قدرتمندی به نام Java Native Interface طراحی شده است که می تواند یک رابط بومی باشد برای استفاده از کیت هایی که به زبان ++C , C توسعه داده شده اند به نام Native Development Kit که با استفاده از این ابزار و برخی از ابزار های دیگر مانند ,Make ,LLDB,Clang... این امکان را خواهید داشت تا کمبود هایی که در زبان جاوا وجود دارد را با استفاده از برنامه نویسی سی و سی پلاس پلاس ، جبران نمایید.

معمولا یکی از پرکاربرد ترین این برنامه ها نوشتن الگوریتم های اختصاصی رمزنگاری می باشد. به این علت که سورسهای زبان جاوا به راحتی با استفاده از تکنیک های مهندسی معکوس استخراج می شوند، به همین علت تهیه چنین الگوریتم هایی در نرم افزار های موبایل حیاتی می باشد. و البته توجه داشته باشید که می توانید از کتابخانه های آماده هم استفاده نمایید حتی سمت زبان سی پلاس پلاس ولی به هرحال اختصاصی نوشتن اینچنین الگوریتم هایی هم خالی از لطف و تجربه نخواهد بود در عین حال هم بلکه پیچیده تر از الگوریتم های آن کتابخانه باشد که بدین ترتیب روش های مهندسی معکوس را هم بسیار سخت تر خواهد کرد ویا عملا غیر ممکن خواهد شد.

وبا توجه به اینکه برنامه هایی که با زبان سی و سی پلاس پلاس که نوشته می شوند مستقیم به اسمبلی تفسیر و سپس به زبان ماشین تبدیل می شوند عملا دی کامپایلر ها توانایی فهمیدن درست سورس کدها را نخواهند داشت وفقط می توانند به کد های اسمبلی که البته خیلی پیچیده تر از کد اصلی برنامه هست تبدیل نمایند.

اکنون پس از این توضیحات کوتاه در زیر سورس کدهای برنامه ای درهم سازی را که از تلفیق چند روش رمزنگاری در اندروید برای استفاده سمت جاوا ی اندرید نوشته ام را خدمت شما ارسال میکنم.

توضیحاتی راجع به الگوریتم ها فعلا نمیدم اگر از دوستان علاقمند بودند در همین بخش اعلام کنند تا توضیح عملکرد را خدمتتان ارائه کنم.

برای استفاده باید ابزار های زیر داشته باشید

JDK1.8 , JRE , Android Studio , NDK rb17 , CMAKE ,LLDB ,Android Build Tools

کلاس native_utils.h


#ifndef BODYPOWER_NATIVE_UTILS_H
#define BODYPOWER_NATIVE_UTILS_H

#include <android/log.h>
#include <iomanip>
#include <locale>
#include <sstream>
#include <memory>

#define TAG_LOG_ANDROID "NativeTagLog"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,TAG_LOG_ANDROID,__VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,TAG_LOG_ANDROID,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,TAG_LOG_ANDROID,__VA_ARGS__)


using namespace std;

namespace BodyPowerNative {

    struct Exp : public exception {

        const
        char* ExceptionDefualtMsg = "error by this exception -> %s";

    public:

        Exp() = default;

        Exp(const Exp &) = default;

        virtual ~Exp() = default;

        static void destory(Exp *my) {
            delete my;
        }

        static unique_ptr<Exp, decltype(&destory)> instance() {
            return unique_ptr<Exp, decltype(&destory)>(new Exp(), &destory);
        }

        static Exp getInstance() {
            return Exp();
        }

        const char* what() const noexcept override {
            return exception::what();
        }

        void printStackTrace(const char *cValue) const {
            LOGE(ExceptionDefualtMsg, cValue);
        };

    };

    class Native_Utils {

    public:

        Native_Utils() = default;

        template<typename T>
        static string NumberToString(T Number) {
            ostringstream ss;
            ss << Number;
            return ss.str();
        }

        template<typename T>
        static T StringToNumber(const string &Text) {
            istringstream ss(Text);
            T result;
            return ss >> result ? result : 0;
        }

    };


    typedef Native_Utils NU;

}

#endif //BODYPOWER_NATIVE_UTILS_H

فایل JniByteArrayWrapper.h


#ifndef BODYPOWER_JNIBYTEARRAYWRAPPER_H
#define BODYPOWER_JNIBYTEARRAYWRAPPER_H

#include <jni.h>
#include <memory>
#include <algorithm>

#define SHA512_BLOCK_SIZE 0x7A

#define SHA512_ENDBYTE_BIGCAPS    0x5A

#define SHA512_MASK 0x5B

#define SHA512_STARTBYTE_CODESMALL_CAPS 0x61

#define SHA512_STARTBYTE_CODEBIG_CAPS 0x41

#define SHA512_STARTBYTECODE_NUMERIC 0x30

#define SHA512_ENDBYTE_CODE_NUMERIC 0x39

#define SHA512_START_DIGEST_BYTECODE_SMALLCAPS 0x60

#define SHA512_START_DIGEST_BYTECODE_BIGCAPS 0x40

#define SHA512_LEFT_SIDESHIFT 0xF

#define SHA512_SPACE_CHARBYTE 0x1B

#define PARAM_LENGTH 0xB

using namespace std;

namespace BodyPowerNative {

    class JniByteArrayWrapper {

    private:
        u_long _key = 0;

        u_long _sKeyLength = 0;

        string _stringKey;

        jsize _dataLength;

        jsize _lenHashData;

        jbyteArray _jb_u;

        JNIEnv *_jniEnv;

        vector<char> vectorBytes;


    public:

        JniByteArrayWrapper() = default; // default ctor

        JniByteArrayWrapper(JNIEnv *&, jbyteArray); //default ctor

        JniByteArrayWrapper(const JniByteArrayWrapper &); // copy ctor

        void const parseJByteArray();

        virtual ~JniByteArrayWrapper();

        bool operator==(const JniByteArrayWrapper &rhs) const; // equal operator overload

        bool operator=(const JniByteArrayWrapper &rhs) const; // assignment operator overload

        bool operator!=(const JniByteArrayWrapper &rhs) const; // not equal operator overload

        const jbyteArray getJBytes() const;

        const JNIEnv &getEnv() const;

        u_long get_key() const;

        u_long get_sKeyLength() const;

        const string &get_stringKey() const;

        jsize get_dataLength() const;

        jsize get_lenHashData() const;

        const vector<char> &getVectorBytes() const;

        void encodingNum();
    };

    typedef JniByteArrayWrapper jByteArrayW;
}

#endif //BODYPOWER_JNIBYTEARRAYWRAPPER_H

فایل JniByteArrayWrapper.cpp


#include "JniByteArrayWrapper.h"
#include "Native_Utils.h"

using namespace BodyPowerNative;


JniByteArrayWrapper::JniByteArrayWrapper(const JniByteArrayWrapper &rhs) {
    _jb_u = rhs._jb_u;
    _jniEnv = rhs._jniEnv;
}

JniByteArrayWrapper::~JniByteArrayWrapper() {
    //delete[]_hash_str;
    vectorBytes.clear();
}

bool jByteArrayW::operator=(const JniByteArrayWrapper &rhs) const {
    return false;
}

bool jByteArrayW::operator==(const JniByteArrayWrapper &rhs) const {
    return _jb_u == rhs._jb_u;
}

bool jByteArrayW::operator!=(const JniByteArrayWrapper &rhs) const {
    return rhs._jb_u != _jb_u;
}

const jbyteArray jByteArrayW::getJBytes() const {
    try{
        jbyteArray _encryptBytes = _jniEnv->NewByteArray(_lenHashData);

        char *_hash_str = new char(_lenHashData);

        transform(vectorBytes.begin(), vectorBytes.end(), _hash_str, [&](char itByte) {
            return itByte;
        });

        _jniEnv->SetByteArrayRegion(_encryptBytes, 0, _lenHashData,
                                    reinterpret_cast<const jbyte *>(_hash_str));
        delete _hash_str;

        return _encryptBytes;
    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }
    return 0;
}

const JNIEnv &jByteArrayW::getEnv() const {
    return *(_jniEnv);
}

void const jByteArrayW::parseJByteArray() {
    try{
        unique_ptr<jbyte> _readByte =
                make_unique<jbyte>();

        _dataLength = _jniEnv->GetArrayLength(_jb_u);

        for (u_int i = 0; i < _dataLength; ++i) {
            _jniEnv->GetByteArrayRegion(_jb_u, i, 1, _readByte.get());
            vectorBytes.push_back(*(_readByte.get()));
        }

        _lenHashData = _dataLength ;
    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }
}

void
jByteArrayW::encodingNum() {

    try {
        string strKey = get_stringKey();
        for (string::iterator _keyIter = strKey.begin();
             _keyIter !=  strKey.end(); ++_keyIter) {

            if (*(_keyIter) >= SHA512_STARTBYTECODE_NUMERIC &&
                *(_keyIter) <= SHA512_ENDBYTE_CODE_NUMERIC) {

                char shiftNum = static_cast<char>(*(_keyIter) + SHA512_LEFT_SIDESHIFT);
                vectorBytes.push_back(shiftNum);
            }
        }

    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

}

u_long
jByteArrayW::get_key() const {
    return _key;
}

u_long
jByteArrayW::get_sKeyLength() const {
    return _sKeyLength;
}

const
string& jByteArrayW::get_stringKey() const {
    return _stringKey;
}

jsize
jByteArrayW::get_dataLength() const {
    return _dataLength;
}

jsize
jByteArrayW::get_lenHashData() const {
    return _lenHashData;
}

const vector<char> &JniByteArrayWrapper::getVectorBytes() const {
    return vectorBytes;
}

JniByteArrayWrapper::JniByteArrayWrapper(JNIEnv *&env, jbyteArray jb) : _jb_u(jb), _jniEnv(env) {}



فایل ParseEncryptAlgol.h


#ifndef BODYPOWER_PARSEENCYRPTALGOL_H
#define BODYPOWER_PARSEENCYRPTALGOL_H

#include <sys/types.h>

namespace BodyPowerNative {

    class JniByteArrayWrapper;

    class ParseEncryptAlgol {
    private:

        u_int num_counter = 0;

        int _extractKeyNum = 0;

        int nShift = 0;

        char digest = 0;

        int *_splitKeyNumArrays;

        JniByteArrayWrapper*& _jniByteArrayWrapper;

    public:
        ParseEncryptAlgol(JniByteArrayWrapper*&);
        char evalAlgol(char byte);

        virtual ~ParseEncryptAlgol();

    };

}


#endif //BODYPOWER_PARSEENCYRPTALGOL_H

فایل ParseEncryptAlgol.cpp


#include "ParseEncryptAlgol.h"
#include "JniByteArrayWrapper.h"

using namespace BodyPowerNative ;

ParseEncryptAlgol::ParseEncryptAlgol(JniByteArrayWrapper*& jniByteArrayWrapper) :
_jniByteArrayWrapper(jniByteArrayWrapper) {

        _splitKeyNumArrays = new int[jniByteArrayWrapper->get_sKeyLength()];
}

ParseEncryptAlgol::~ParseEncryptAlgol() {
    delete[]_splitKeyNumArrays;
}

char ParseEncryptAlgol::evalAlgol(char _readByte) {
    {
        if (num_counter < _jniByteArrayWrapper->get_sKeyLength()) {
            _extractKeyNum = _splitKeyNumArrays[num_counter++];
        } else {
            num_counter = 0;
            _extractKeyNum = _splitKeyNumArrays[num_counter++];
        }

        if (_readByte >= SHA512_STARTBYTECODE_NUMERIC &&
            _readByte <= SHA512_ENDBYTE_CODE_NUMERIC) {

            return 0 ;// security::encodingNum(_readByte);

        } else if (_readByte + _extractKeyNum > SHA512_BLOCK_SIZE) { //z 122

            nShift = _extractKeyNum > (SHA512_BLOCK_SIZE - _readByte) ?
                     _extractKeyNum - (SHA512_BLOCK_SIZE - _readByte) :
                     (SHA512_BLOCK_SIZE - _readByte) - _extractKeyNum;
            digest = static_cast<char>(SHA512_START_DIGEST_BYTECODE_SMALLCAPS + nShift);
            return digest;

        } else if (_readByte + _extractKeyNum > SHA512_ENDBYTE_BIGCAPS &&
                   _readByte <= SHA512_ENDBYTE_BIGCAPS) { //Z 90

            nShift = _extractKeyNum > (SHA512_ENDBYTE_BIGCAPS - _readByte) ?
                     _extractKeyNum - (SHA512_ENDBYTE_BIGCAPS - _readByte) :
                     (SHA512_ENDBYTE_BIGCAPS - _readByte) - _extractKeyNum;
            digest = static_cast<char>(SHA512_START_DIGEST_BYTECODE_BIGCAPS + nShift);
            return digest;

        } else {

            return static_cast<char>(_readByte + _extractKeyNum);

        }

    }
}



فایل security.h


#ifndef BODYPOWER_SECURITY_H
#define BODYPOWER_SECURITY_H

#include <jni.h>
#include <string.h>
#include <memory>
#include "Native_Utils.h"

#define Java_App_Class "com/nativeDb/materialDesign/MyApplication"

namespace BodyPowerNative {

    class JniByteArrayWrapper;

    const
    char *BASE_URL =
            "--/";

    const
    char *BODY_POWER_API_SOURCE_REF =
            "phpSource/";

    const
    char *COACH_PHOTO_BASE_URL =
            "CoachPhoto/";

    const
    char *SUPP_PHOTO_BASE_URL =
            "SuppImages/";

    const
    char *COACH_DATA_BASE_URL =
            "getItems";

    const
    char *COACH_DATA_BASE_URL_FAILD =
            "getItemsFaild";

    const
    char *PROFILE_SEND_BASE_URL =
            "FetchProfileRow";

    const
    char *PHOTO_PROFILE_SEND_BASE_URL =
            "uploadPhoto";

    const
    char *REGISTER_USER_BASE_URL =
            "updateUser";

    const
    char *EXIST_USER_BASE_URL =
            "checkExistUser";

    const
    char *UPD_URL =
            "updateMentorList";

    const
    char *SUPP_PROD_URL =
            "getItems_supp";

    static u_int posSepChar =0 ;

    typedef unsigned int sha2_32t;

    typedef unsigned long sha2_64t;

    typedef jsize sha1_32t;

    typedef jbyte sha1_8;

    typedef struct sha512 {

    public:

        //unsigned bitMask :1; 

        char *hash_str;

        char *hash_out = nullptr;

        inline sha512(sha1_32t lenHashData) {
            hash_str = new char[lenHashData];
            if(!hash_str)
                throw Exp::getInstance();
        }

        inline sha512(const sha512& rhs){
            hash_str = new char[strlen(rhs.hash_str)];
            if(!hash_str)
                throw Exp::getInstance();
            this->hash_str = rhs.hash_str;
            if(hash_out != nullptr){
                this->hash_out = rhs.hash_out;
            }
        }

        inline ~sha512() {
            delete[]hash_str;
            hash_str=nullptr;

            if(hash_out != nullptr) {
                delete[]hash_out;
                hash_out= nullptr;
            }
        }

        inline sha512& operator=(const sha512& rhs){
            if(&rhs != this){
                delete[]hash_str;
                this->hash_str = rhs.hash_str;
                if(hash_out != nullptr){
                    delete[]hash_out;
                    this->hash_out = rhs.hash_out;
                }
            }
            return *this;
        }

    } sha512_ctx;


    class security {

    public:

        security() = default;

        ~security(){};

        static
        jbyteArray encryptAlgol(
                JNIEnv *, jobject , jbyteArray);

        static
        jbyteArray encrypt(
                JNIEnv *, jobject , jbyteArray);

        static
        jbyteArray decrypt(
                JNIEnv *, jobject , jbyteArray);

        static
        jint customRand(
                JNIEnv *env, jobject , jint , jint );

        static
        jstring baseApiUrl(
                JNIEnv *, jobject );

        static
        jstring mentorApiUrl(
                JNIEnv *, jobject );

        static
        jstring mentorPhotoApiUrl(
                JNIEnv *, jobject );

        static
        jstring suppPhotoApiUrl(
                JNIEnv *, jobject );

        static
        jstring mentorDataApiUrl(
                JNIEnv *, jobject );

        static
        jstring mentorDataFaildApiUrl(
                JNIEnv *, jobject );

        static
        jstring profileDataApiUrl(
                JNIEnv *, jobject );

        static
        jstring profilePhotoApiUrl(
                JNIEnv *, jobject );

        static
        jstring registerUserApiUrl(
                JNIEnv *, jobject );

        static
        jstring privacyUserApiUrl(
                JNIEnv *, jobject );

        static
        jstring updateMentorApiUrl(
                JNIEnv *, jobject );

        static
        jstring suppProdApiUrl(
                JNIEnv *, jobject );

        static
        jobjectArray mapParamToStringArray
                (JNIEnv *, jobject);

        static
        void splitKeyNum(int *&, const string&);

        static
        char encodingNum(const jbyte *);

        static
        char encodingNum(const char);

    private:

        static
        void encodingNum(string, char *&, jsize);

        static
        char decodingNum(const jbyte *);

        static
        string decodingNum(JNIEnv *, const jbyteArray &);

        static
        u_int getEndReadBytePos(JNIEnv *, const jbyteArray &, jsize);

        static void
        revAlgol(JNIEnv *&, _jbyteArray *, JniByteArrayWrapper *&, char *&);

        static void
        revAlgol(JNIEnv *&, _jbyteArray *, JniByteArrayWrapper *&, char *&, jbyteArray &);

    };


    typedef security SC;

    static JNINativeMethod method_table[] = {
            {"encrypt",               "([B)[B",                (void *) SC::encrypt},
            {"decrypt",               "([B)[B",                (void *) SC::decrypt},
            {"customRand",            "(II)I",                 (void *) SC::customRand},
            {"baseApiUrl",            "()Ljava/lang/String;",  (void *) SC::baseApiUrl},
            {"mentorApiUrl",          "()Ljava/lang/String;",  (void *) SC::mentorApiUrl},
            {"mentorPhotoApiUrl",     "()Ljava/lang/String;",  (void *) SC::mentorPhotoApiUrl},
            {"mentorDataApiUrl",      "()Ljava/lang/String;",  (void *) SC::mentorDataApiUrl},
            {"suppPhotoApiUrl",       "()Ljava/lang/String;",  (void *) SC::suppPhotoApiUrl},
            {"mentorDataFaildApiUrl", "()Ljava/lang/String;",  (void *) SC::mentorDataFaildApiUrl},
            {"profileDataApiUrl",     "()Ljava/lang/String;",  (void *) SC::profileDataApiUrl},
            {"profilePhotoApiUrl",    "()Ljava/lang/String;",  (void *) SC::profilePhotoApiUrl},
            {"registerUserApiUrl",    "()Ljava/lang/String;",  (void *) SC::registerUserApiUrl},
            {"privacyUserApiUrl",     "()Ljava/lang/String;",  (void *) SC::privacyUserApiUrl},
            {"updateMentorApiUrl",    "()Ljava/lang/String;",  (void *) SC::updateMentorApiUrl},
            {"suppProdApiUrl",        "()Ljava/lang/String;",  (void *) SC::suppProdApiUrl},
            {"mapParamToStringArray", "()[Ljava/lang/String;", (void *) SC::mapParamToStringArray}
    };

    extern "C" {
    jint JNI_OnLoad(JavaVM *vm, void *reserved) {

        JNIEnv *env;
        if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
            return -1;
        } else {
            jclass clazz = env->FindClass(Java_App_Class);

            if (clazz) {
                env->RegisterNatives(clazz, method_table,
                                     sizeof(method_table) / sizeof(method_table[0]));
                env->DeleteLocalRef(clazz);
                return JNI_VERSION_1_6;
            } else {
                return -1;
            }
        }

    }
    }

}


#endif //BODYPOWER_SECURITY_H

فایل security.cpp

/*
 const char *str = (*env)->GetStringUTFChars(env, s, 0);
 (*env)->ReleaseStringUTFChars(env, s, str);
*/

//string _jskey = static_cast<ostringstream*>( &(ostringstream() << _key) )->str();

/*

 uint64_t features = android_getCpuFeatures();
if ((features & ANDROID_CPU_ARM_FEATURE_NEON) == 0) {
  //NEON is not available
} else {
  //NEON is available
}
 int android_getCpuCount(void);

*/

#include "security.h"
#include "ParseEncryptAlgol.h"
#include "JniByteArrayWrapper.h"

#define sum32(x)   (x += *(_readByte.operator->()))

#define shift_r32(_ex_num, _read_byt) nShift = (_ex_num > (SHA512_BLOCK_SIZE - _read_byt) ? \
                                               _ex_num - (SHA512_BLOCK_SIZE - _read_byt) : \
                                               (SHA512_BLOCK_SIZE - _read_byt) - _ex_num)

#define shift_l32(_ex_num, _read_byt) nShift = (_ex_num > (SHA512_ENDBYTE_BIGCAPS - _read_byt) ? \
                                               _ex_num - (SHA512_ENDBYTE_BIGCAPS - _read_byt) : \
                                               (SHA512_ENDBYTE_BIGCAPS - _read_byt) - _ex_num)

#define compile_num(i)  ctx->hash_str[i]    = encodingNum(_readByte.operator->());

#define compile_wbuf97(i)  ctx->hash_str[i] = static_cast<char>(SHA512_START_DIGEST_BYTECODE_SMALLCAPS + nShift);

#define compile_wbuf65(i)  ctx->hash_str[i] = static_cast<char>(SHA512_START_DIGEST_BYTECODE_BIGCAPS + nShift);

#define compile_wbuf(i)  ctx->hash_str[i]   = static_cast<char>(*(_readByte.operator->()) + _extractKeyNum);

#define compile_dec_wbuf27(i) ctx->hash_str[i] = static_cast<char>(SHA512_SPACE_CHARBYTE);

#define compile_dec_num(i) ctx->hash_str[i] = decodingNum(_readByte.operator->());

#define compile_dec_wbuf65(i)  ctx->hash_str[i] = static_cast<char>( SHA512_MASK - \
                  ((*(_readByte.operator->()) - SHA512_STARTBYTE_CODEBIG_CAPS) > _extractKeyNum ? \
                  (*(_readByte.operator->()) - SHA512_STARTBYTE_CODEBIG_CAPS) - _extractKeyNum : \
                     _extractKeyNum - (*(_readByte.operator->()) - SHA512_STARTBYTE_CODEBIG_CAPS)) );

#define compile_dec_wbuf65_2(i)  ctx->hash_str[i] = static_cast<char>(SHA512_BLOCK_SIZE - (_extractKeyNum - \
                  (*(_readByte.operator->()) - SHA512_START_DIGEST_BYTECODE_SMALLCAPS)));

#define compile_dec_wbuf97(i)  ctx->hash_str[i] = static_cast<char>(nlShift);

#define compile_dec_wbuf(i) ctx->hash_str[i] = static_cast<char>(*(_readByte.operator->()) - _extractKeyNum);


using namespace BodyPowerNative;

jbyteArray security::encryptAlgol(JNIEnv *env, jobject j, jbyteArray jb) {


    JniByteArrayWrapper *jniByteArrayWrapper = new JniByteArrayWrapper(env, jb);
    jniByteArrayWrapper->parseJByteArray();
    jbyteArray _encryptBytes = env->NewByteArray(jniByteArrayWrapper->get_lenHashData());
    char *hash_str = new char[jniByteArrayWrapper->get_lenHashData()];
    vector<char> vect = jniByteArrayWrapper->getVectorBytes();


    /*    
    ParseEncryptAlgol* parseEncryptAlgol= new ParseEncryptAlgol(jniByteArrayWrapper);
    transform(vect.begin(), vect.end(), hash_str,[](char byte){
        return parseEncryptAlgol->evalAlgol(byte);
    });*/

    /*security sec;
    int* p ;
    p = reinterpret_cast<int*>(&sec);
    char* c;
    c = reinterpret_cast<char*>(&sec);
    */

    jniByteArrayWrapper->encodingNum();

    env->SetByteArrayRegion(_encryptBytes, 0, jniByteArrayWrapper->get_lenHashData(),
                            reinterpret_cast<const jbyte *>(hash_str));

    delete[]hash_str;
    delete jniByteArrayWrapper;

    return _encryptBytes;
}

jbyteArray
SC::encrypt(JNIEnv *env, jobject jclazz, jbyteArray _data) {

    try {

        auto num_counter = 0;

        auto _extractKeyNum = 0;

        auto nShift = 0;

        sha2_64t _key = 0;

        sha1_32t _dataLength = env->GetArrayLength(_data);

        if (_dataLength == 0)
            throw Exp::getInstance();

        unique_ptr<sha1_8> _readByte =
                make_unique<sha1_8>();

        if(!_readByte)
            throw Exp::getInstance();

        for (sha2_32t i = 0; i < _dataLength; ++i) {
            env->GetByteArrayRegion(_data, i, 1, _readByte.get());
            sum32(_key);
        }

        string _stringKey = NU::NumberToString(_key);

        sha2_64t _sKeyLength = _stringKey.length();

        int *_splitKeyNumArrays{new int[_sKeyLength]};
        if(_splitKeyNumArrays == nullptr)
            throw Exp::getInstance();

        sha1_32t lenHashData = _dataLength + static_cast<int>(_sKeyLength);

        sha512_ctx *ctx = new sha512_ctx(lenHashData);

        jbyteArray _encryptBytes = env->NewByteArray(lenHashData);

        splitKeyNum(_splitKeyNumArrays, _stringKey);

        for (sha2_32t i = 0; i < _dataLength; ++i) {

            if (num_counter >= _sKeyLength) {
                num_counter = 0;
            }
            _extractKeyNum = _splitKeyNumArrays[num_counter++];

            env->GetByteArrayRegion(_data, i, 1, _readByte.operator->());
            jbyte jbRead = *(_readByte.operator->());

            if (jbRead >= SHA512_STARTBYTECODE_NUMERIC &&
                jbRead <= SHA512_ENDBYTE_CODE_NUMERIC) {

                compile_num(i);

            } else if (jbRead + _extractKeyNum > SHA512_BLOCK_SIZE) { //z 122

                shift_r32(_extractKeyNum, jbRead);
                compile_wbuf97(i);

            } else if (jbRead + _extractKeyNum > SHA512_ENDBYTE_BIGCAPS &&
                       jbRead <= SHA512_ENDBYTE_BIGCAPS) { //Z 90

                shift_l32(_extractKeyNum, jbRead);
                compile_wbuf65(i);

            } else {

                compile_wbuf(i);

            }
        }

        encodingNum(NU::NumberToString(_key), ctx->hash_str, _dataLength);

        {
            env->SetByteArrayRegion(_encryptBytes, 0, lenHashData,
                                    reinterpret_cast<const jbyte *>(ctx->hash_str));

            JniByteArrayWrapper *jniByteArrayWrapper;

            revAlgol(env, _encryptBytes, jniByteArrayWrapper, ctx->hash_out);

            env->SetByteArrayRegion(_encryptBytes, 0, jniByteArrayWrapper->get_lenHashData(),
                                    reinterpret_cast<const jbyte *>(ctx->hash_out));
            delete jniByteArrayWrapper;
            jniByteArrayWrapper = nullptr;
        }

        _readByte.reset(); // delete smart pointer
        //delete _readByte.operator->();
        delete[]_splitKeyNumArrays;
        delete ctx;
        env->DeleteLocalRef(_data);
        _splitKeyNumArrays = nullptr;

        return _encryptBytes;
    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

    return nullptr;
}

void
SC::revAlgol(JNIEnv *&env, _jbyteArray *_encryptBytes,
             JniByteArrayWrapper *&jbw, char *&hash_out) {

    jbw = new JniByteArrayWrapper(env, _encryptBytes);
    jbw->parseJByteArray();

    hash_out = new char[jbw->get_lenHashData()];

    vector<char> vect = jbw->getVectorBytes();

    transform(vect.rbegin(), vect.rend(), hash_out, [&](char byte) {
        //__android_log_print(ANDROID_LOG_ERROR,TAG_LOG_ANDROID,"this lambda -> %lu" ,jbw->get_key());
        return byte;
    });
}


void
SC::revAlgol(JNIEnv *&env, _jbyteArray *_encryptBytes,
             JniByteArrayWrapper *&jbw, char *&hash_str, jbyteArray &_encryptBytes_dest) {

    revAlgol(env, _encryptBytes, jbw, hash_str);

    _encryptBytes_dest = env->NewByteArray(jbw->get_lenHashData());

    env->SetByteArrayRegion(_encryptBytes_dest, 0, jbw->get_lenHashData(),
                            reinterpret_cast<const jbyte *>(hash_str));
}

char
SC::encodingNum(const jbyte * _keyIter) {
    char shiftNum;

    try {
        shiftNum = static_cast<char>(*(_keyIter) - SHA512_LEFT_SIDESHIFT);
    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

    return shiftNum;
}

char
SC::encodingNum(const char byte) {
    char shiftNum;

    try {
        shiftNum = static_cast<char>(byte - SHA512_LEFT_SIDESHIFT);
    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

    return shiftNum;
}

char
SC::decodingNum(const jbyte *_keyIter) {

    char shiftNum;
    try {
        shiftNum = static_cast<char>(*(_keyIter) + SHA512_LEFT_SIDESHIFT);
    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

    return shiftNum;
}

void
SC::encodingNum(string strNum, char *&hash_str, jsize len) {

    try {

        for (string::iterator _keyIter = strNum.begin();
             _keyIter != strNum.end(); ++_keyIter) {

            if (*(_keyIter) >= SHA512_STARTBYTECODE_NUMERIC &&
                *(_keyIter) <= SHA512_ENDBYTE_CODE_NUMERIC) {

                char shiftNum = static_cast<char>(*(_keyIter) - SHA512_LEFT_SIDESHIFT);
                hash_str[len++] = shiftNum;
            }
        }

    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

}

string
security::decodingNum(JNIEnv *env, const jbyteArray &_data) {

    try {

        jsize _dataLength = env->GetArrayLength(_data);

        unique_ptr<jbyte> _readByte =
                make_unique<jbyte>();
        if(!_readByte)
            throw Exp::getInstance();

        string shiftNum;

        char numChar;

        //sum all bytes.
        posSepChar = getEndReadBytePos(env, _data, _dataLength);

        for (u_int _k = _dataLength - posSepChar; _k < _dataLength; ++_k) {
            env->GetByteArrayRegion(_data, _k, 1, _readByte.operator->());

            if (*(_readByte.operator->()) >= (SHA512_STARTBYTECODE_NUMERIC - SHA512_LEFT_SIDESHIFT)
                && *(_readByte.operator->()) <= (SHA512_ENDBYTE_CODE_NUMERIC - SHA512_LEFT_SIDESHIFT)) {

                numChar = static_cast<char>(*(_readByte.operator->()) + SHA512_LEFT_SIDESHIFT);
                shiftNum += numChar;

            }

        }

        _readByte.release();
        delete _readByte.operator->();

        return shiftNum;

    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

    return nullptr;
}

u_int
SC::getEndReadBytePos(JNIEnv *env, const jbyteArray &_data, jsize _dataLength) {

    sha2_64t _key = 0;

    unique_ptr<jbyte> _readByte =
            make_unique<jbyte>();

    if(!_readByte)
        throw Exp::getInstance();

    for (u_int i = 0; i < _dataLength; ++i) {
        env->GetByteArrayRegion(_data, i, 1, _readByte.operator->());
        sum32(_key);
    }

    _readByte.reset(); // delete smart pointer
    //delete _readByte.operator->();

    return static_cast<u_int>(NU::NumberToString(_key).length());
}

jbyteArray
SC::decrypt(JNIEnv *env, jobject jclazz, jbyteArray _encryptData) {

    try {

        jbyteArray _encryptBytes2;

        {
            JniByteArrayWrapper *jniByteArrayWrapper;

            char *hash_in;

            revAlgol(env, _encryptData, jniByteArrayWrapper, hash_in, _encryptBytes2);

            delete[]hash_in;
            hash_in= nullptr;
            delete jniByteArrayWrapper;
            jniByteArrayWrapper= nullptr;
        }

        string _stringKey = decodingNum(env, _encryptBytes2);

        auto num_counter = 0;

        auto _extractKeyNum = 0;

        unique_ptr<jbyte> _readByte =
                make_unique<jbyte>();
        if(!_readByte)
            throw Exp::getInstance();

        jsize _dataLength = env->GetArrayLength(_encryptBytes2);

        if (_dataLength == 0)
            throw Exp::instance();

        auto _orginalSizeOfHashArrays = _dataLength - posSepChar;

        sha512_ctx *ctx = new sha512_ctx(_orginalSizeOfHashArrays);

        jbyteArray _encryptBytes = env->NewByteArray(_orginalSizeOfHashArrays);

        auto _keyLen = _stringKey.length();

        int *_splitKeyNumArrays = new int[_keyLen];

        splitKeyNum(_splitKeyNumArrays, _stringKey);

        for (u_int i = 0; i < _dataLength - posSepChar; ++i) {

            if (i >= _dataLength - posSepChar) {

                compile_dec_wbuf27(i);

            } else {

                if (num_counter < _keyLen) {
                    _extractKeyNum = _splitKeyNumArrays[num_counter++];
                } else {
                    num_counter = 0;
                    _extractKeyNum = _splitKeyNumArrays[num_counter++];
                }

                env->GetByteArrayRegion(_encryptBytes2, i, 1, _readByte.operator->());
                jbyte jbRead = *(_readByte.operator->());

                if (jbRead >= (SHA512_STARTBYTECODE_NUMERIC - SHA512_LEFT_SIDESHIFT)
                    && jbRead <= (SHA512_ENDBYTE_CODE_NUMERIC - SHA512_LEFT_SIDESHIFT)) {

                    compile_dec_num(i);

                } else if (jbRead < SHA512_MASK &&
                           jbRead - _extractKeyNum <= SHA512_ENDBYTE_BIGCAPS) {

                    auto nlShift = jbRead - _extractKeyNum;

                    if (nlShift <= SHA512_START_DIGEST_BYTECODE_BIGCAPS) {

                        compile_dec_wbuf65(i);

                    } else {

                        compile_dec_wbuf97(i);

                    }
                } else if (*(_readByte.get()) - _extractKeyNum < SHA512_STARTBYTE_CODESMALL_CAPS) {

                    compile_dec_wbuf65_2(i);
                } else {

                    compile_dec_wbuf(i);

                }
            }
        }

        env->SetByteArrayRegion(_encryptBytes, 0, _orginalSizeOfHashArrays,
                                reinterpret_cast<const jbyte *>(ctx->hash_str));

        _readByte.release();
        delete _readByte.operator->();
        delete[]_splitKeyNumArrays;
        delete ctx;
        env->DeleteLocalRef(_encryptBytes2);
        env->DeleteLocalRef(_encryptData);
        _splitKeyNumArrays= nullptr;

        return _encryptBytes;

    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

    return nullptr;
}


void
SC::splitKeyNum(int *&_splitKeyNumArrays, const string &_stringKey) {

    try {

        auto _sCounter = 0;
        string str_num ;

        for(auto const _key : _stringKey){
            str_num = NU::NumberToString(_key);
            *(_splitKeyNumArrays+_sCounter++) = NU::StringToNumber<int>(str_num);
        }

    } catch (exception &E) {
        static_cast<Exp &>(E).printStackTrace(E.what());
    }

}

jint
SC::customRand(JNIEnv *env, jobject jclazz, jint total, jint total_draw) {

/*    if (total < total_draw)
        return 0;

    srand(static_cast<u_int>(time(NULL))); // create the seeds

    u_int *balls =
            new u_int[static_cast<u_int>(total_draw)]; // create new array

    for (u_int i = 0; i < total_draw; i++) {
        balls[i] = static_cast<u_int>(rand()) + total + 1; // genrate the rand number
        for (u_int j = 0; j < i + 1; j++) {
            if (balls[i] == balls[j] &&
                i != j) { // if duplicate rand number forward and recreate rand
                i--;
                break;
            } else if (j == i) { // if rand number is that uniqe.
                return reinterpret_cast<jint>(env->NewIntArray(balls[i]));
            }
        }

    }
    delete[] balls;*/
    return 0;
}

jstring
SC::baseApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(BASE_URL);
}

jstring
SC::mentorApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(BODY_POWER_API_SOURCE_REF);
}

jstring
SC::mentorPhotoApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(COACH_PHOTO_BASE_URL);
}

jstring
SC::mentorDataApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(COACH_DATA_BASE_URL);
}

jstring
SC::mentorDataFaildApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(COACH_DATA_BASE_URL_FAILD);
}

jstring
SC::suppPhotoApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(SUPP_PHOTO_BASE_URL);
}

jstring
SC::profileDataApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(PROFILE_SEND_BASE_URL);
}

jstring
SC::profilePhotoApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(PHOTO_PROFILE_SEND_BASE_URL);
}

jstring
SC::registerUserApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(REGISTER_USER_BASE_URL);
}

jstring
SC::privacyUserApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(EXIST_USER_BASE_URL);
}

jstring
SC::updateMentorApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(UPD_URL);
}

jstring
SC::suppProdApiUrl(JNIEnv *env, jobject jclazz) {
    return env->NewStringUTF(SUPP_PROD_URL);
}


jobjectArray
SC::mapParamToStringArray(JNIEnv *env, jobject jclazz) {

    char *message[PARAM_LENGTH]
            = {const_cast<char *>("type"),
               const_cast<char *>("action"),
               const_cast<char *>("user"),
               const_cast<char *>("pass"),
               const_cast<char *>("group"),
               const_cast<char *>("netid"),
               const_cast<char *>("consumer"),
               const_cast<char *>("timestam"),
               const_cast<char *>("agent"),
               const_cast<char *>("login"),
               const_cast<char *>("profile")};

    jobjectArray ret = env->NewObjectArray(PARAM_LENGTH,
                              env->FindClass("java/lang/String"),
                              env->NewStringUTF(""));

    for (int ic_ = 0; ic_ < PARAM_LENGTH; ic_++) {
        env->SetObjectArrayElement(
                ret, ic_, env->NewStringUTF(message[ic_]));
    }

    return ret;
}

و برای استفاده هم در سمت اندورید هم به روش های زیر انجام دهید.

    static {
        System.loadLibrary("native-lib");
    }
    
    public
    static native byte[] encrypt(byte[] bytes);

    public
    static native byte[] decrypt(byte[] bytes);

    public
    static native int customRand(int total,int totalDraw);

    public
    static native String baseApiUrl();

    public
    static native String mentorApiUrl();

    public
    static native String mentorPhotoApiUrl();

    public
    static native String suppPhotoApiUrl();

    public
    static native String mentorDataApiUrl();

    public
    static native String mentorDataFaildApiUrl();

    public
    static native String profileDataApiUrl();

    public
    static native String profilePhotoApiUrl();

    public
    static native String registerUserApiUrl();

    public
    static native String privacyUserApiUrl();

    public
    static native String updateMentorApiUrl();

    public
    static native String suppProdApiUrl();
    
    public
    static native String[] mapParamToStringArray();
public interface ApiPropertiesService {

    @Native
    String  BASE_URL                    = baseApiUrl();

    @Native
    String BODY_API_URL                 = BASE_URL + mentorApiUrl();

    @Native
    String  MENTOR_PHOTO_BASE_URL       = BASE_URL + mentorPhotoApiUrl();

    @Native
    String  SUPP_PHOTO_BASE_URL         = BASE_URL + suppPhotoApiUrl();

    @Native
    String COACH_DATA_BASE_URL          = BODY_API_URL + mentorDataApiUrl() ;

    @Native
    String COACH_DATA_BASE_URL_FAILD    = BODY_API_URL + mentorDataFaildApiUrl() ;

    @Native
    String PROFILE_SEND_BASE_URL        = BODY_API_URL + profileDataApiUrl() ;

    @Native
    String PHOTO_PROFILE_SEND_BASE_URL  = BODY_API_URL + profilePhotoApiUrl();

    @Native
    String REGISTER_USER_BASE_URL       = BODY_API_URL + registerUserApiUrl();

    @Native
    String EXIST_USER_BASE_URL          = BODY_API_URL + privacyUserApiUrl();

    @Native
    String UPD_URL                      = BODY_API_URL + updateMentorApiUrl();

    @Native
    String SUPP_URL                     = BODY_API_URL + suppProdApiUrl();

    @Native
    String[] MAP_PARAM                 = mapParamToStringArray();
}
    String pass = "abcd";
    encryption(pass.toByte());
    
    private String encryption(byte[] jByte) {

        try {
            if (jByte != null && jByte.length > 0) {
                byte[] enc = encrypt(jByte);
                StringBuilder byteToStr = new StringBuilder();
                for (byte readByte : enc) {
                    byteToStr.append((char) readByte);
                }

                return byteToStr.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    private String decryption(byte[] encryptedBytes) {

        try {
            if (encryptedBytes != null && encryptedBytes.length > 0) {
                byte[] dec = decrypt(encryptedBytes);
                StringBuilder byteToStr = new StringBuilder();
                for (byte chars : dec) {
                    if (chars != 27)
                        byteToStr.append((char) chars);
                }
                Log.i("NativeTagLog", "dec with c++ : " + byteToStr.toString() + " and len dec data : " + byteToStr.length());
                return byteToStr.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

 

  • پسندیدن 1

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

برای ارسال دیدگاه یک حساب کاربری ایجاد کنید یا وارد حساب خود شوید

برای اینکه بتوانید دیدگاهی ارسال کنید نیاز دارید که کاربر سایت شوید

ایجاد یک حساب کاربری

برای حساب کاربری جدید در سایت ما ثبت نام کنید. عضویت خیلی ساده است !

ثبت نام یک حساب کاربری جدید

ورود به حساب کاربری

دارای حساب کاربری هستید؟ از اینجا وارد شوید

ورود به حساب کاربری

  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

  • مطالب مشابه

    • توسط Saman
      سلام وخسته نباشد
      چطور میتونم از کد های جاوا در پروژه های QML استفاده کنم
    • توسط xarion
      سلام. من چند وقتی هست که می خوام برای اندروید با کیوت یه اپ ساده رو Run کنم و درگیر خیلی چیزا بودم تا به این مرحله برسم. الان می خوام با مشخصات زیر یه از یه نمونه کد Qt برای اندروید اجرا بگیرم ولی توی Build به مشکل بر خوردم.
       
      Qt 5.11.1 Compiler: MinGW 4.9 Kit: android arm7 JDK: 8 NDK:17 SDK: Update to the last version که در موقع build با این خطا مواجه می شم.
      Exception in thread "main" java.util.zip.ZipException: error in opening zip file at java.util.zip.ZipFile.open(Native Method) at java.util.zip.ZipFile.(ZipFile.java:225) at java.util.zip.ZipFile.(ZipFile.java:155) at java.util.zip.ZipFile.(ZipFile.java:169) at org.gradle.wrapper.Install.unzip(Install.java:215) at org.gradle.wrapper.Install.access$600(Install.java:27) at org.gradle.wrapper.Install$1.call(Install.java:75) at org.gradle.wrapper.Install$1.call(Install.java:48) at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:69) at org.gradle.wrapper.Install.createDist(Install.java:48) at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107) at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61) Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Fusion.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Imagine.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Material.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Universal.impl Building the android package failed! 03:39:16: The process "C:\Qt\5.11.1\android_armv7\bin\androiddeployqt.exe" exited with code 14. Error while building/deploying project gallery (kit: Android for armeabi-v7a (GCC 4.9, Qt 5.11.1 for Android armv7)) When executing step "Build Android APK" ممنون می شم اگر بتونید راهنمایی کنید.
×