美文网首页音视频后端砖头
android使用openssl实现C++与JAVA互相RSA,

android使用openssl实现C++与JAVA互相RSA,

作者: youxiaochen | 来源:发表于2022-04-22 23:43 被阅读0次

    这里主要是openssl常用的编码Base64, 摘要算法MD5,对称加密AES, 非对称加密RSA与Java互通

    一: openssl交叉编译

    openssl源码下载, NDK下载
    这里下载的openssl版本是1.1.0f, NDK版本是21, Ubuntu18,解压openssl代码包执行 config或者Configure可以查看编译时的附加参数列表, NDK如何编译,在developer NDK文档中都有详细介绍,也有编译时的示例脚本,要编译的第三库也一般会提供config, configure相关编译参数文件,./执行即可查看

    NDK官方文档

    就是根据下载的NDK包配置好编译时对应的CC(编译C代码)/CXX(编译C++),在NDK21时都已经采用clang(弃用了gcc)和SYSROOT等路径,openssl1.1.0f是纯C写的只要配置CC就行,这里编译的shell脚本在项目源码中,已经编译了arm64-v8a和armeabi-v7a的包

    二:openssl与java互相加解密

    openssl中文手册,这里只介绍C++与JAVA相互编解,加解密时的注意点

    1:Base64

    android已经提供好android.util.Base64类, 编解码时注意byte[]转换编码格式一致即可

    const char *data = env->GetStringUTFChars(_data, JNI_FALSE);
    

    //GetStringUTFChars 与java代码data.getBytes(UTF8)对应编码一致即可

    Base64.encode(data.getBytes(UTF8))
    
    2:MD5

    同样在byte[]转换时统一编码格式,摘要算法后的byte[]统一转16进制及统一大小写即可

    std::string MD5Code::md5(const char *src, size_t src_len) {
        unsigned char md[16];
        MD5((unsigned char *) src, src_len, md);
        char md5str[33]{0};  //MD5结果 32 + \0
        for (int i = 0; i < 16; i++) {
            sprintf(md5str, "%s%02x", md5str, md[i]);
        }
        return md5str;
    }
    
    3:AES

    加密模式如ECB,CBC,填充方式一致即可如PKCS5Padding,ZEROPading,加密后的byte[]转换base64时的编码也要一致 (如下openssl部分填充方式代码)

    void Padding::padding(std::string &src, int alignSize, PaddingModel mode) {
        int remainder = src.length() % alignSize;
        int paddingSize = (remainder == 0) ? alignSize : (alignSize - remainder);
        switch (mode) {
            case PKCS5OR7:
                src.append(paddingSize, paddingSize);
                break;
            case ZERO:
            default:
                src.append(paddingSize, 0);
                break;
        }
    }
    
    4: RSA (一般用加密AES需要的KEY)

    openssl的公私钥采用的是PEM格式,JAVA采用的是DER格式,openssl生成的PEM格式的公私钥通过bouncycastlel转换成DER格式及生成密钥时的长度一致即可, 加解密时的填充方式如(PKCS1Padding)一致
    如部分转换PEM成DER格式公钥代码

    public static PublicKey getFromPemPublicKey(String public_key) throws Exception {
            byte[] keyBytes = new sun.misc.BASE64Decoder().decodeBuffer(public_key);
            ASN1InputStream in = new ASN1InputStream(keyBytes);
            DERObject obj = in.readObject();
            RSAPublicKeyStructure pStruct = RSAPublicKeyStructure.getInstance(obj);
            RSAPublicKeySpec spec = new RSAPublicKeySpec(pStruct.getModulus(), pStruct.getPublicExponent());
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePublic(spec);
        }
    

    测试如


    测试!!

    最后是源码地址

    相关文章

      网友评论

        本文标题:android使用openssl实现C++与JAVA互相RSA,

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