├── .gitignore ├── .idea └── checkstyle-idea.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── key.keystore ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── github │ │ └── yutianzuo │ │ └── myapplication │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── yutianzuo │ │ │ └── myapplication │ │ │ ├── BeanTest.java │ │ │ ├── BizNetWrapper.java │ │ │ ├── Crypto.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── github │ └── yutianzuo │ └── myapplication │ └── ExampleUnitTest.java ├── build.gradle ├── curl_native ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── github │ │ └── yutianzuo │ │ └── curl_native │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── cacert.pem │ ├── cpp │ │ ├── aes_cbc.h │ │ ├── android_utils.h │ │ ├── include │ │ │ ├── curl │ │ │ │ ├── curl.h │ │ │ │ ├── curlver.h │ │ │ │ ├── easy.h │ │ │ │ ├── mprintf.h │ │ │ │ ├── multi.h │ │ │ │ ├── stdcheaders.h │ │ │ │ ├── system.h │ │ │ │ └── typecheck-gcc.h │ │ │ ├── mbedtls │ │ │ │ ├── aes.h │ │ │ │ ├── aria.h │ │ │ │ ├── asn1.h │ │ │ │ ├── asn1write.h │ │ │ │ ├── base64.h │ │ │ │ ├── bignum.h │ │ │ │ ├── build_info.h │ │ │ │ ├── camellia.h │ │ │ │ ├── ccm.h │ │ │ │ ├── chacha20.h │ │ │ │ ├── chachapoly.h │ │ │ │ ├── check_config.h │ │ │ │ ├── cipher.h │ │ │ │ ├── cmac.h │ │ │ │ ├── compat-2.x.h │ │ │ │ ├── config_psa.h │ │ │ │ ├── constant_time.h │ │ │ │ ├── ctr_drbg.h │ │ │ │ ├── debug.h │ │ │ │ ├── des.h │ │ │ │ ├── dhm.h │ │ │ │ ├── ecdh.h │ │ │ │ ├── ecdsa.h │ │ │ │ ├── ecjpake.h │ │ │ │ ├── ecp.h │ │ │ │ ├── entropy.h │ │ │ │ ├── error.h │ │ │ │ ├── gcm.h │ │ │ │ ├── hkdf.h │ │ │ │ ├── hmac_drbg.h │ │ │ │ ├── legacy_or_psa.h │ │ │ │ ├── lms.h │ │ │ │ ├── mbedtls_config.h │ │ │ │ ├── md.h │ │ │ │ ├── md5.h │ │ │ │ ├── memory_buffer_alloc.h │ │ │ │ ├── net_sockets.h │ │ │ │ ├── nist_kw.h │ │ │ │ ├── oid.h │ │ │ │ ├── pem.h │ │ │ │ ├── pk.h │ │ │ │ ├── pkcs12.h │ │ │ │ ├── pkcs5.h │ │ │ │ ├── pkcs7.h │ │ │ │ ├── platform.h │ │ │ │ ├── platform_time.h │ │ │ │ ├── platform_util.h │ │ │ │ ├── poly1305.h │ │ │ │ ├── private_access.h │ │ │ │ ├── psa_util.h │ │ │ │ ├── ripemd160.h │ │ │ │ ├── rsa.h │ │ │ │ ├── sha1.h │ │ │ │ ├── sha256.h │ │ │ │ ├── sha512.h │ │ │ │ ├── ssl.h │ │ │ │ ├── ssl_cache.h │ │ │ │ ├── ssl_ciphersuites.h │ │ │ │ ├── ssl_cookie.h │ │ │ │ ├── ssl_ticket.h │ │ │ │ ├── threading.h │ │ │ │ ├── timing.h │ │ │ │ ├── version.h │ │ │ │ ├── x509.h │ │ │ │ ├── x509_crl.h │ │ │ │ ├── x509_crt.h │ │ │ │ └── x509_csr.h │ │ │ ├── openssl │ │ │ │ ├── aes.h │ │ │ │ ├── asn1.h │ │ │ │ ├── asn1_mac.h │ │ │ │ ├── asn1t.h │ │ │ │ ├── async.h │ │ │ │ ├── bio.h │ │ │ │ ├── blowfish.h │ │ │ │ ├── bn.h │ │ │ │ ├── buffer.h │ │ │ │ ├── camellia.h │ │ │ │ ├── cast.h │ │ │ │ ├── cmac.h │ │ │ │ ├── cms.h │ │ │ │ ├── comp.h │ │ │ │ ├── conf.h │ │ │ │ ├── conf_api.h │ │ │ │ ├── crypto.h │ │ │ │ ├── ct.h │ │ │ │ ├── des.h │ │ │ │ ├── dh.h │ │ │ │ ├── dsa.h │ │ │ │ ├── dtls1.h │ │ │ │ ├── e_os2.h │ │ │ │ ├── ebcdic.h │ │ │ │ ├── ec.h │ │ │ │ ├── ecdh.h │ │ │ │ ├── ecdsa.h │ │ │ │ ├── engine.h │ │ │ │ ├── err.h │ │ │ │ ├── evp.h │ │ │ │ ├── hmac.h │ │ │ │ ├── idea.h │ │ │ │ ├── kdf.h │ │ │ │ ├── lhash.h │ │ │ │ ├── md2.h │ │ │ │ ├── md4.h │ │ │ │ ├── md5.h │ │ │ │ ├── mdc2.h │ │ │ │ ├── modes.h │ │ │ │ ├── obj_mac.h │ │ │ │ ├── objects.h │ │ │ │ ├── ocsp.h │ │ │ │ ├── opensslconf.h │ │ │ │ ├── opensslv.h │ │ │ │ ├── ossl_typ.h │ │ │ │ ├── pem.h │ │ │ │ ├── pem2.h │ │ │ │ ├── pkcs12.h │ │ │ │ ├── pkcs7.h │ │ │ │ ├── rand.h │ │ │ │ ├── rc2.h │ │ │ │ ├── rc4.h │ │ │ │ ├── rc5.h │ │ │ │ ├── ripemd.h │ │ │ │ ├── rsa.h │ │ │ │ ├── safestack.h │ │ │ │ ├── seed.h │ │ │ │ ├── sha.h │ │ │ │ ├── srp.h │ │ │ │ ├── srtp.h │ │ │ │ ├── ssl.h │ │ │ │ ├── ssl2.h │ │ │ │ ├── ssl3.h │ │ │ │ ├── stack.h │ │ │ │ ├── symhacks.h │ │ │ │ ├── tls1.h │ │ │ │ ├── ts.h │ │ │ │ ├── txt_db.h │ │ │ │ ├── ui.h │ │ │ │ ├── whrlpool.h │ │ │ │ ├── x509.h │ │ │ │ ├── x509_vfy.h │ │ │ │ └── x509v3.h │ │ │ └── psa │ │ │ │ ├── crypto.h │ │ │ │ ├── crypto_builtin_composites.h │ │ │ │ ├── crypto_builtin_primitives.h │ │ │ │ ├── crypto_compat.h │ │ │ │ ├── crypto_config.h │ │ │ │ ├── crypto_driver_common.h │ │ │ │ ├── crypto_driver_contexts_composites.h │ │ │ │ ├── crypto_driver_contexts_primitives.h │ │ │ │ ├── crypto_extra.h │ │ │ │ ├── crypto_platform.h │ │ │ │ ├── crypto_se_driver.h │ │ │ │ ├── crypto_sizes.h │ │ │ │ ├── crypto_struct.h │ │ │ │ ├── crypto_types.h │ │ │ │ └── crypto_values.h │ │ ├── jni.cpp │ │ ├── lib │ │ │ ├── arm64 │ │ │ │ ├── libcrypto.a │ │ │ │ ├── libcurl.a │ │ │ │ ├── libmbedcrypto.a │ │ │ │ ├── libmbedtls.a │ │ │ │ ├── libmbedx509.a │ │ │ │ ├── libnghttp2.a │ │ │ │ └── libssl.a │ │ │ ├── arm64bak │ │ │ │ ├── libcrypto.a │ │ │ │ ├── libcurl.a │ │ │ │ ├── libmbedcrypto.a │ │ │ │ ├── libmbedtls.a │ │ │ │ ├── libmbedx509.a │ │ │ │ ├── libnghttp2.a │ │ │ │ └── libssl.a │ │ │ ├── v7a │ │ │ │ ├── libcurl.a │ │ │ │ ├── libmbedcrypto.a │ │ │ │ ├── libmbedtls.a │ │ │ │ ├── libmbedx509.a │ │ │ │ ├── libnghttp2.a │ │ │ │ └── libssl.a │ │ │ ├── x86 │ │ │ │ ├── libcrypto.a │ │ │ │ ├── libcurl.a │ │ │ │ ├── libcurl.la │ │ │ │ ├── libssl.a │ │ │ │ └── pkgconfig │ │ │ │ │ └── libcurl.pc │ │ │ └── x86_64 │ │ │ │ ├── libcurl.a │ │ │ │ ├── libmbedcrypto.a │ │ │ │ ├── libmbedtls.a │ │ │ │ ├── libmbedx509.a │ │ │ │ └── libnghttp2.a │ │ ├── manager │ │ │ ├── httpmanager.h │ │ │ ├── requestmanager.cpp │ │ │ ├── requestmanager.h │ │ │ └── threadpool.h │ │ ├── miscs.h │ │ ├── request │ │ │ ├── downloadrequest.h │ │ │ ├── getrequest.h │ │ │ ├── postfilerequest.h │ │ │ ├── postrequest.h │ │ │ ├── putrequest.h │ │ │ └── request.h │ │ ├── sha.h │ │ ├── string_x.h │ │ └── tools │ │ │ └── timeutils.h │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── yutianzuo │ │ │ └── curl_native │ │ │ ├── HttpCallback.java │ │ │ ├── HttpManager.java │ │ │ ├── JniCurl.java │ │ │ ├── RequestManager.java │ │ │ └── utils │ │ │ ├── Misc.java │ │ │ ├── PriorityThreadFactory.java │ │ │ ├── ThreadHelper.java │ │ │ └── ThreadUtils.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── github │ └── yutianzuo │ └── curl_native │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── native_crash_handler ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── android_utils.h │ └── native_crash_handler.cpp │ └── java │ └── com │ └── github │ └── yutianzuo │ └── native_crash_handler │ └── NativeCrashHandler.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /.idea/ 4 | /.idea/caches/ 5 | /local.properties 6 | /.idea/libraries 7 | /.idea/modules.xml 8 | /.idea/workspace.xml 9 | .DS_Store 10 | /build 11 | /captures 12 | .externalNativeBuild 13 | /app/release/ -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # android-curl 2 | so支持arm64、x86_64架构,可以在真机或者模拟器上运行。 3 | 编译功能包括curl+mbedtls+nghttp2. 4 | 独立的aar module,可以直接引入项目使用,结合app中的封装demo,可以快速集成进入项目中。 5 | 更多请见文档:https://www.jianshu.com/p/895a4e5052e2 6 | 7 | keywords: android curl jni ndk https http openssl http2.0 libnghttp2 nghttp2 8 | 9 | 关键字:安卓 curl jni ndk https https openssl http2.0 libnghttp2 nghttp2 10 | 11 | ----------------------------------------------------------------- 12 | 996.icu 13 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | signingConfigs { 5 | SignConfig { 6 | keyAlias 'key0' 7 | keyPassword '123456' 8 | storeFile file('key.keystore') 9 | storePassword '123456' 10 | } 11 | } 12 | compileSdkVersion 28 13 | defaultConfig { 14 | applicationId "com.github.yutianzuo.curl" 15 | minSdkVersion 20 16 | targetSdkVersion 20 17 | versionCode 1 18 | versionName "1.0" 19 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 20 | ndk { 21 | abiFilters 'armeabi-v7a', 'arm64-v8a' ,'x86_64'//only 64bit 22 | } 23 | } 24 | buildTypes { 25 | release { 26 | signingConfig signingConfigs.SignConfig 27 | minifyEnabled true 28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 29 | } 30 | debug { 31 | signingConfig signingConfigs.SignConfig 32 | } 33 | } 34 | buildToolsVersion '28.0.3' 35 | productFlavors { 36 | } 37 | lintOptions { 38 | checkReleaseBuilds false 39 | // Or, if you prefer, you can continue to check for errors in release builds, 40 | // but continue the build even when errors are found: 41 | abortOnError false 42 | } 43 | } 44 | repositories { 45 | flatDir { 46 | dirs 'libs' 47 | } 48 | } 49 | 50 | dependencies { 51 | implementation fileTree(include: ['*.jar'], dir: 'libs') 52 | implementation 'androidx.appcompat:appcompat:1.0.0' 53 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 54 | testImplementation 'junit:junit:4.12' 55 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 56 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 57 | implementation project(':curl_native') 58 | implementation project(':native_crash_handler') 59 | //implementation(name: 'curl_native-release', ext: 'aar') 60 | } 61 | -------------------------------------------------------------------------------- /app/key.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yutianzuo/android-curl/f5520318c164e05bcc58eb1398aec37c98fbdfb9/app/key.keystore -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | 22 | 23 | 24 | -keep class com.github.yutianzuo.curl_native.HttpManager{*;} -------------------------------------------------------------------------------- /app/src/androidTest/java/com/github/yutianzuo/myapplication/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.github.yutianzuo.myapplication; 2 | 3 | import android.content.Context; 4 | import androidx.test.platform.app.InstrumentationRegistry; 5 | import androidx.test.ext.junit.runners.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.github.yutianzuo.myapplication", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/yutianzuo/myapplication/BeanTest.java: -------------------------------------------------------------------------------- 1 | package com.github.yutianzuo.myapplication; 2 | 3 | import java.io.Serializable; 4 | 5 | public class BeanTest implements Serializable { 6 | public String rep; 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/yutianzuo/myapplication/Crypto.java: -------------------------------------------------------------------------------- 1 | package com.github.yutianzuo.myapplication; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.util.Base64; 6 | 7 | import javax.crypto.Cipher; 8 | import javax.crypto.SecretKey; 9 | import javax.crypto.spec.IvParameterSpec; 10 | import javax.crypto.spec.SecretKeySpec; 11 | 12 | public class Crypto { 13 | /** 14 | * 传入文本内容,返回 SHA-256 串 15 | */ 16 | public String SHA256(final String strText) { 17 | return SHA(strText, "SHA-256"); 18 | } 19 | 20 | /** 21 | * 字符串 SHA 加密 22 | */ 23 | private String SHA(final String strText, final String strType) { 24 | // 返回值 25 | String strResult = null; 26 | 27 | // 是否是有效字符串 28 | if (strText != null && strText.length() > 0) { 29 | try { 30 | // SHA 加密开始 31 | // 创建加密对象 并傳入加密類型 32 | MessageDigest messageDigest = MessageDigest.getInstance(strType); 33 | // 传入要加密的字符串 34 | messageDigest.update(strText.getBytes()); 35 | // 得到 byte 類型结果 36 | byte byteBuffer[] = messageDigest.digest(); 37 | 38 | // 將 byte 轉換爲 string 39 | StringBuffer strHexString = new StringBuffer(); 40 | // 遍歷 byte buffer 41 | for (int i = 0; i < byteBuffer.length; i++) { 42 | String hex = Integer.toHexString(0xff & byteBuffer[i]); 43 | if (hex.length() == 1) { 44 | strHexString.append('0'); 45 | } 46 | strHexString.append(hex); 47 | } 48 | // 得到返回結果 49 | strResult = strHexString.toString(); 50 | } catch (NoSuchAlgorithmException e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | 55 | return strResult; 56 | } 57 | 58 | /** 59 | * 传入文本内容,返回 SHA-512 串 60 | */ 61 | public String SHA512(final String strText) { 62 | return SHA(strText, "SHA-512"); 63 | } 64 | 65 | public byte[] aesEncrypt(String key, String iv, String content) { 66 | byte[] byteRet = null; 67 | try { 68 | SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 69 | byte[] initParam = iv.getBytes("UTF-8"); 70 | IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); 71 | //https://stackoverflow.com/questions/29232705/encrypt-text-to-aes-cbc-pkcs7padding 72 | //Java only provides PKCS#5 padding, but it is the same as PKCS#7 padding. See this question on Crypto.SE: 73 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 74 | cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); 75 | // cipher.update(content.getBytes("UTF-8")); 76 | byteRet = cipher.doFinal(content.getBytes("UTF-8")); 77 | // strRet = Base64.getEncoder().encodeToString(result); 78 | } catch (Throwable e) { 79 | 80 | } 81 | return byteRet; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 |