Git Product home page Git Product logo

muzipiao / gmobjc Goto Github PK

View Code? Open in Web Editor NEW
346.0 8.0 88.0 84.5 MB

SM2/SM3/SM4/ECDH crypto library based on OpenSSL.

Home Page: https://muzipiao.github.io/2019/08/iOS-%E4%BD%BF%E7%94%A8-SM2-SM4-%E5%8A%A0%E8%A7%A3%E5%AF%86-SM2-%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE%E5%8F%8A-SM3-%E6%91%98%E8%A6%81/

License: MIT License

Objective-C 99.97% Ruby 0.02% Swift 0.01%
sm2 sm3 sm4 objective-c ecdh sm2-encryption sm2-signature-verification sm3-digest-algorithm swift ios

gmobjc's Introduction

GMObjC

Build Status Pod Version Pod Platform Pod License Carthage compatible SwiftPM compatible codecov

简体中文 Readme 文档

OpenSSL 1.1.1 and above adds support for chinese SM2/SM3/SM4 encryption algorithm, based on OpenSSL, SM2 asymmetric encryption, SM2 signature verification, ECDH key agreement, SM3 digest algorithm, and SM4 symmetric encryption are used for OC encapsulation.

Getting Started

Run the following command in the terminal:

git clone https://github.com/muzipiao/GMObjC.git

cd GMObjC

pod install

open GMObjC.xcworkspace

Requirements

Depends on OpenSSL 1.1.1 or above, has been packaged as a Framework, and uploaded cocoapods, can be dragged into the project to install directly, or use cocoapods to configure the Podfile file pod GMOpenSSL installation; and import the system framework Security.framework.

Installation

The method of using GMObjC in the project is as follows:

  • Use CocoaPods
  • Use Carthage
  • Compile to Framework/XCFramework
  • Use Swift Package Manager
  • Drag into the project source code

CocoaPods

CocoaPods is the easiest and most convenient way to integrate. Edit Podfile, add

pod'GMObjC'

Then execute pod install. GMObjC relies on OpenSSL 1.1.1 and above. CocoaPods does not support different versions of the same static library. If you encounter OpenSSL conflicts with third-party libraries, for example, Baidu MapKit depends on a lower version of the OpenSSL static library, a dependency conflict will occur. .

Common solutions to OpenSSL conflicts:

Method 1: Upgrade the third party library using OpenSSL to version 1.1.1 or higher. GMObjC directly shares this OpenSSL library. There is no need to add an OpenSSL dependent library for GMObjC separately, just manually integrate GMObjC;

Method 2: Compiling GMObjC into a dynamic library can resolve such conflicts. You can automatically compile GMObjC into a dynamic library through Carthage. See the next step for specific operations.

Carthage

Carthage can automatically compile a third-party framework into a dynamic framework (Dynamic framework). If it is not installed, execute brew update and brew install carthage to install, and then create a file named Cartfile (similar to Podfile), edit and add The name of the compiled third party library is like github "muzipiao/GMObjC", and then execute carthage update --use-xcframeworks.

# Install carthage
brew update && brew install carthage
# Create Cartfile file and write it to github "muzipiao/GMObjC"
touch Cartfile && echo 'github "muzipiao/GMObjC"' >> Cartfile
# Pull and compile into a dynamic library, and you can find GMObjC.framework in Carthage/Build/iOS/ under the current command directory
carthage update --use-xcframeworks

After the compilation is successful, open Carthage to view the generated file directory. Carthage/Build/iOS/GMObjC.xcframework is the compiled dynamic library. Just drag the dynamic library into the project.

Note: GMObjC.xcframework is a dynamic library, you need to select the Embed & Sign mode, and you do not need to import the openssl.framework library separately. If Carthage fails to compile, download the project source code, open the project file in the GMObjCFramework folder, and execute command + b to compile manually.

Swift Package Manager

GMObjC support SwiftPM from version 3.3.0. To use SwiftPM, you should use Xcode 11 to open your project. Click File -> Swift Packages -> Add Package Dependency, enter GMObjC repo's URL. Or you can login Xcode with your GitHub account and just type GMObjC to search.

After select the package, you can choose the dependency type (tagged version, branch or commit). Then Xcode will setup all the stuff for you.

If you're a framework author and use GMObjC as a dependency, update your Package.swift file:

dependencies: [
    .package(url: "https://github.com/muzipiao/GMObjC.git", from: "3.3.7")
],

Direct integration

Download the latest code from Git, find the GMObjC folder at the same level as the README, drag the GMObjC folder into the project, and import the header file GMObjC.h where you need to use SM2, SM4 encryption, decryption, and signature verification. Sign, calculate SM3 summary, etc.

Points to note when integrating OpenSSL:

  1. Tools depend on OpenSSL. You can install OpenSSL through pod GMOpenSSL, or download openssl.framework, find GMOpenSSL/openssl.framework, and drag into the project. can.
  2. If you need to self-compile OpenSSL, there is an OpenSSL_BUILD folder in the GMOpenSSL project directory, terminal cd switch to this directory, first execute ./build -libssl.sh command to compile and generate .a file, after waiting, execute ./create-openssl-framework.sh command to package as framework, then openssl.framework appears in the directory.
  3. The packaged static library does not expose the national secret header files. Open the downloaded source code and drag sm2.h, sm3.h, and sm4.h under the crypto/include/internal path to the openssl.framework/Headers file Just clip it.

How To Use

SM2 encryption and decryption

SM2 encryption and decryption are very simple, encrypt the incoming plaintext and public key to be encrypted, and decrypt the incoming ciphertext and private key. The code:

// public key
NSString *pubKey = @"0408E3FFF9505BCFAF9307E665E9229F4E1B3936437A870407EA3D97886BAFBC9"
                    "C624537215DE9507BC0E2DD276CF74695C99DF42424F28E9004CDE4678F63D698";
// private key
NSString *prikey = @"90F3A42B9FE24AB196305FD92EC82E647616C3A3694441FB3422E7838E24DEAE";

// plaintext
NSString *plaintext = @"123456"; // ordinary plaintext
NSString *plainHex = @"313233343536"; // Hex format character plain text (The Hex code of 123456 is 313233343536)
NSData *plainData = [NSData dataWithBytes:"123456" length:6]; // NSData format plain text

// sm2 encryption
NSString *enResult1 = [GMSm2Utils encryptText:plaintext publicKey:pubKey]; // encrypt ordinary string
NSString *enResult2 = [GMSm2Utils encryptHex:plainHex publicKey:pubKey]; // Encrypted Hex encoding format string
NSData *enResult3 = [GMSm2Utils encryptData:plainData publicKey:pubKey]; // Encrypt NSData type data

// sm2 decrypt
NSString *deResult1 = [GMSm2Utils decryptToText:enResult1 privateKey:priKey]; // Decrypt to plain text of ordinary string
NSString *deResult2 = [GMSm2Utils decryptToHex:enResult2 privateKey:priKey]; // Decrypt to plain text in Hex format
NSData *deResult3 = [GMSm2Utils decryptToData:enResult3 privateKey:priKey]; // Decrypt to plain text in NSData format

note:

  1. The public key used by OpenSSL starts with 04, which means the uncompressed public key format. The public key returned in the background may not carry 04, and manual splicing is required.
  2. The decryption result returned by the background may be the original ciphertext C1C3C2 format without standard encoding, and the encryption and decryption of OpenSSL requires the ASN1 encoding format, so in the process of interacting with the background, ASN1 encoding and decoding may be required.

SM2 Signature Verification

SM2 private key signature, public key verification, anti-tampering or identity verification. Pass in plain text, private key and user ID when signing; pass in plain text, signature, public key and user ID when signing, code:

// public key
NSString *pubKey = @"0408E3FFF9505BCFAF9307E665E9229F4E1B3936437A870407EA3D97886BAFBC9"
                    "C624537215DE9507BC0E2DD276CF74695C99DF42424F28E9004CDE4678F63D698";
// private key
NSString *prikey = @"90F3A42B9FE24AB196305FD92EC82E647616C3A3694441FB3422E7838E24DEAE";

// plaintext
NSString *plaintext = @"123456"; // ordinary plaintext
NSString *plainHex = @"313233343536"; // Hex format character plain text (The Hex code of 123456 is 313233343536)
NSData *plainData = [NSData dataWithBytes:"123456" length:6]; // NSData format plain text

// When userID is passed in nil or empty, the default is 1234567812345678; when it is not empty, the signature and verification need the same ID
NSString *userID = @"[email protected]"; // userID of ordinary string
NSString *userHex = [GMUtils stringToHex:userID]; // userID in Hex format
NSData *userData = [userID dataUsingEncoding:NSUTF8StringEncoding]; // userID in NSData format

// The signature result is a 128-byte Hex format string spliced ​​by RS, the first 64 bytes are R, and the last 64 bytes are S
NSString *signStr1 = [GMSm2Utils signText:plaintext privateKey:priKey userID:userID];
NSString *signStr2 = [GMSm2Utils signHex:plainHex privateKey:priKey userHex:userHex];
NSString *signStr3 = [GMSm2Utils signData:plainData priKey:priKey userData:userData];

// Verify the signature, YES means the verification passed
BOOL isOK1 = [GMSm2Utils verifyText:plaintext signRS:signStr1 publicKey:pubKey userID:userID];
BOOL isOK2 = [GMSm2Utils verifyHex:plainHex signRS:signStr2 publicKey:pubKey userHex:userHex];
BOOL isOK3 = [GMSm2Utils verifyData:plainData signRS:signStr3 pubKey:pubKey userData:userData];

// Encoded in Der format, Der encoding and decoding should be the same as the original value
NSString *derSign1 = [GMSm2Utils derEncode:signStr1];
NSString *derSign2 = [GMSm2Utils derEncode:signStr2];
NSString *derSign3 = [GMSm2Utils derEncode:signStr3];

// Decode into RS string format, RS spliced ​​128-byte Hex format string, the first 64 bytes are R, the last 64 bytes are S
NSString *rs1 = [GMSm2Utils derDecode:derSign1];
NSString *rs2 = [GMSm2Utils derDecode:derSign2];
NSString *rs3 = [GMSm2Utils derDecode:derSign3];

note:

  1. The user ID can be passed a null value. When passing a null value, the OpenSSL default user ID is used. The default user definition in OpenSSL is #define SM2_DEFAULT_USERID "1234567812345678". The client and server user IDs must be consistent.
  2. During the interaction between the client and the background, assuming the background signature, the client verifies the signature, and the signature returned by the background is in DER encoding format, the signature needs to be DER decoded first, and then the signature is verified. In the same way, if the client signs, the background verifies the signature, and encodes and decodes according to whether the background requires RS splicing format signature or DER format.

ECDH key agreement

The ECDH_compute_key() in OpenSSL performs elliptic curve Diffie-Hellman key agreement, which can negotiate the same key when both parties are transmitting in plain text.

Negotiation process:

  1. The client randomly generates a pair of public and private keys clientPublicKey, clientPrivateKey;
  2. The server randomly generates a pair of public and private keys serverPublicKey, serverPrivateKey;
  3. The two parties exchange public keys clientPublicKey and serverPublicKey using network requests or other methods, and the private keys are kept by themselves;
  4. Client calculation clientKey = ECDH_compute_key(clientPrivateKey, serverPublicKey);
  5. Server-side calculation serverKey = ECDH_compute_key(serverPrivateKey, clientPublicKey);
  6. The clientKey and serverKey calculated by both parties should be equal, and this key can be used as the key for symmetric encryption.
// The client generates a pair of public and private keys
NSArray *clientKey = [GMSm2Utils createKeyPair];
NSString *cPubKey = clientKey[0];
NSString *cPriKey = clientKey[1];

// The server generates a pair of public and private keys
NSArray *serverKey = [GMSm2Utils createKeyPair];
NSString *sPubKey = serverKey[0];
NSString *sPriKey = serverKey[1];

// The client obtains the public key sPubKey from the server, and the client negotiates a 32-byte symmetric key clientECDH, which is 64 bytes after being converted to Hex
NSString *clientECDH = [GMSm2Utils computeECDH:sPubKey privateKey:cPriKey];
// The client sends the public key cPubKey to the server, and the server negotiates a 32-byte symmetric key serverECDH, which is 64 bytes after being converted to Hex
NSString *serverECDH = [GMSm2Utils computeECDH:cPubKey privateKey:sPriKey];

// In the case of all plaintext transmission, the client and the server negotiate an equal symmetric key, clientECDH==serverECDH is established
if ([clientECDH isEqualToString:serverECDH]) {
    NSLog(@"ECDH key negotiation is successful, the negotiated symmetric key is:\n%@", clientECDH);
}else{
    NSLog(@"ECDH key negotiation failed");
}

SM2 key file read-write (PEM/DER)

The SM2 public and private key format may be PEM or DER format, which can be operated with GMSm2Bio.

NSString *filePath = @"PEM or DER file address";
// Read SM2 public and private key from PEM file
NSString *pubPemKey = [GMSm2Bio readPublicKeyFromPemFile:filePath];
NSString *priPemKey = [GMSm2Bio readPrivateKeyFromPemFile:filePath];
// Read SM2 public and private key from DER file
NSString *pubDerKey = [GMSm2Bio readPublicKeyFromDerFile:filePath];
NSString *priDerKey = [GMSm2Bio readPrivateKeyFromDerFile:filePath];

NSString *savePath = @"Save SM2 public or private keys to the sandbox of the PEM/DER file";
// Save the public key string starting with 04 as a PEM or DER file, and return YES if the save is successful, otherwise NO
BOOL success1 = [GMSm2Bio savePublicKeyToPemFile:pubKey filePath:pubPemPath];
BOOL success2 = [GMSm2Bio savePublicKeyToDerFile:pubKey filePath:pubDerPath];
// Save the private key string as a PEM or DER file, return YES if saved successfully, otherwise NO
BOOL success3 = [GMSm2Bio savePrivateKeyToPemFile:priKey filePath:priPemPath];
BOOL success4 = [GMSm2Bio savePrivateKeyToDerFile:priKey filePath:priDerPath];

// Create a PEM or DER format key pair file, the array element 0 is the address of the public key file, and element 1 is the address of the private key file
NSArray<NSString *> *derFilesArray = [GMSm2Bio createDerKeyPairFiles];
NSArray<NSString *> *pemFilesArray = [GMSm2Bio createPemKeyPairFiles];

SM4 encryption and decryption

SM4 encryption and decryption are very simple, encrypt the incoming string and key to be encrypted, and decrypt the incoming ciphertext and key, the code:

  • ECB electronic codebook mode, the ciphertext is divided into blocks of equal length (not enough to fill), and block by block is encrypted.
  • CBC ciphertext grouping link mode, the ciphertext of the previous group and the plaintext of the current group are XORed and then encrypted.
NSString *sm4Key = @"EA4EBDC1DCEAEC733FFD358BA15E8DCD"; // 32-byte Hex encoding format string key
NSString *ivec = @"1AFE5CC82D2DE304343FED0AF5FDE7FA"; // 32-byte initialization vector, required for CBC encryption mode

// plaintext
NSString *plaintext = @"123456"; // ordinary plaintext
NSData *plainData = [NSData dataWithBytes:"123456" length:6]; // NSData format plain text

// ECB encryption mode
NSString *ecbCipertext = [GMSm4Utils ecbEncryptText:plaintext key:sm4Key]; // Encrypt plain text of ordinary string
NSData *ecbCipherData = [GMSm4Utils ecbEncryptData:plainData key:sm4Key]; // Encrypt NSData type plaintext
// ECB decryption mode
NSString *ecbPlaintext = [GMSm4Utils ecbDecryptText:ecbCipertext key:sm4Key];
NSData *ecbDecryptData = [GMSm4Utils ecbDecryptData:ecbCipherData key:sm4Key];

// CBC encryption mode
NSString *cbcCipertext = [GMSm4Utils cbcEncryptText:plaintext key:sm4Key IV:ivec];
NSData *cbcCipherData = [GMSm4Utils cbcEncryptData:plainData key:sm4Key IV:ivec];
// CBC decryption mode
NSString *cbcPlaintext = [GMSm4Utils cbcDecryptText:cbcCipertext key:sm4Key IV:ivec];
NSData *cbcDecryptData = [GMSm4Utils cbcDecryptData:cbcCipherData key:sm4Key IV:ivec];

SM3 Digest

Similar to md5、sha1,SM3 digest algorithm can perform digest calculation on text files, and the digest length is a 64-byte Hex encoding format string.

// Original
NSString *plaintext = @"123456"; // normal original text
NSData *plainData = [NSData dataWithBytes:"123456" length:6]; // NSData format original text

// String summary
NSString *textDigest = [GMSm3Utils hashWithString:plaintext];
// Summary of NSData
NSString *dataDigest = [GMSm3Utils hashWithData:plainData];

HMAC calculation Digest

HMAC algorithm calculates the Digest, and the calculated Digest length is the same as that of the original Digest algorithm.

NSString *plaintext = @"123456"; // plaintext
NSString *randomKey = @"qwertyuiop1234567890"; // Key passed from the server
// HMAC uses SM3 digest algorithm
NSString *hmacSM3 = [GMSm3Utils hmacWithSm3:randomKey plaintext:plaintext];
// HMAC uses MD5 digest algorithm
NSString *hmacMD5 = [GMSm3Utils hmac:GMHashType_MD5 key:randomKey plaintext:plaintext];
// HMAC uses SHA1 digest algorithm
NSString *hmacSHA1 = [GMSm3Utils hmac:GMHashType_SHA1 key:randomKey plaintext:plaintext];
// HMAC uses SHA224 digest algorithm
NSString *hmacSHA224 = [GMSm3Utils hmac:GMHashType_SHA224 key:randomKey plaintext:plaintext];
// HMAC uses SHA256 digest algorithm
NSString *hmacSHA256 = [GMSm3Utils hmac:GMHashType_SHA256 key:randomKey plaintext:plaintext];
// HMAC uses SHA384 digest algorithm
NSString *hmacSHA384 = [GMSm3Utils hmac:GMHashType_SHA384 key:randomKey plaintext:plaintext];
// HMAC uses SHA512 digest algorithm
NSString *hmacSHA512 = [GMSm3Utils hmac:GMHashType_SHA512 key:randomKey plaintext:plaintext];

ASN1 encoding and decoding

OpenSSL encodes the SM2 encryption results in ASN1 format. During decryption, the ciphertext encoding format is also required to be ASN1 format. After decoding, the original ciphertext spliced in c1c3c2 order is obtained.

// public key
NSString *pubKey = @"0408E3FFF9505BCFAF9307E665E9229F4E1B3936437A870407EA3D97886BAFBC9"
                    "C624537215DE9507BC0E2DD276CF74695C99DF42424F28E9004CDE4678F63D698";
// private key
NSString *prikey = @"90F3A42B9FE24AB196305FD92EC82E647616C3A3694441FB3422E7838E24DEAE";

// plaintext
NSString *plaintext = @"123456"; // ordinary plaintext
NSString *plainHex = @"313233343536"; // Hex format character plain text (The Hex code of 123456 is 313233343536)
NSData *plainData = [NSData dataWithBytes:"123456" length:6]; // NSData format plain text

// sm2 encryption result, ASN1 encoded cipher text
NSString *enResult1 = [GMSm2Utils encryptText:plaintext publicKey:pubKey]; // encrypt ordinary string
NSString *enResult2 = [GMSm2Utils encryptHex:plainHex publicKey:pubKey]; // Encrypted Hex encoding format string
NSData *enResult3 = [GMSm2Utils encryptData:plainData publicKey:pubKey]; // Encrypt NSData type data

// ASN1 decoding, decode the ciphertext in ASN1 encoding format string, array or NSData
NSString *c1c3c2Result1 = [GMSm2Utils asn1DecodeToC1C3C2:enResult1]; // Decode to c1c3c2 string
NSArray<NSString *> *c1c3c2Result2 = [GMSm2Utils asn1DecodeToC1C3C2Array:enResult2]; // decoded as @[c1,c3,c2]
NSData *c1c3c2Result3 = [GMSm2Utils asn1DecodeToC1C3C2Data:enResult3]; // decoded as data spliced ​​by c1c3c2

// ASN1 encoding, re-encoding the decoded c1c3c2 ciphertext into ASN1 format, which should be exactly the same as enResult1, enResult2, and enResult3
NSString *asn1Result1 = [GMSm2Utils asn1EncodeWithC1C3C2:c1c3c2Result1];
NSString *asn1Result2 = [GMSm2Utils asn1EncodeWithC1C3C2Array:c1c3c2Result2];
NSData *asn1Result3 = [GMSm2Utils asn1EncodeWithC1C3C2Data:c1c3c2Result3];

Ciphertext format conversion

After ASN1 decodes the ciphertext, the ciphertext sequence obtained is c1c3c2, and other platforms may need ciphertext in the order of c1c2c3; For example, the Java side uses bouncycastle for SM2 encryption, and the ciphertext may be the ciphertext beginning with 04 and arranged according to c1c2c3.

OpenSSL decryption requires the ciphertext to be arranged in c1c3c2 and ASN1 encoding format. Conversion is required in both cases. For the ciphertext encrypted by bouncycastle, the ciphertext format needs to be changed from c1c2c3 to c1c3c2, then ASN1 coding and decryption.

Generally, the ciphertext does not contain ciphertext format identification. As for whether it does, it can be confirmed by observation or with other platforms. The common identification at the beginning of the ciphertext.

  • 02 or 03 compressed representation
  • 04 uncompressed representation
  • 06 or 07 mixed representation
NSString *ciphertext = @"C1C2C3 Sequential ciphertext";
// Change the ciphertext in c1c2c3 order to c1c3c2 order
NSString *c1c3c2 = [GMSm2Utils convertC1C2C3ToC1C3C2:c1c2c3 hasPrefix:NO];
// ASN1 encoding, encoding the ciphertext in c1c3c2 order into ASN1 format
NSString *asn1Result = [GMSm2Utils asn1EncodeWithC1C3C2:c1c3c2];
// Decrypt to plain text string
NSString *deResult1 = [GMSm2Utils decryptToText:asn1Result privateKey:priKey]; 
// If necessary, you can change the ciphertext in c1c3c2 order to c1c2c3 order
NSString *c1c2c3 = [GMSm2Utils convertC1C3C2ToC1C2C3:c1c3c2 hasPrefix:NO];

Ciphertext splitting principle: Assuming that the ciphertext without ASN1 coding is in hex coding (hexadecimal coding) format and arranged in the order of c1c2c3, it is known that C1 length is fixed at 128 bytes and C3 length is fixed at 64 bytes, then C2 length = total length of ciphertext string - C1 length 128 - C3 length, so C1, C2 and C3 strings are obtained respectively and spliced freely.

Generate public and private keys

Based on the SM2 recommended curve (a 256-bit elliptic curve in the prime field), a public and private key is generated.

NSArray *keyPair = [GMSm2Utils createKeyPair];
NSString *pubKey = keyPair[0]; // The public key at the beginning of 04, Hex encoding format
NSString *priKey = keyPair[1]; // Private key, Hex encoding format

SM2 Curves

  1. GM/T 0003-2012 standard recommended parameters sm2p256v1 (NID_sm2);
  2. SM2 If you need to use other curves, call [GMSm2Utils setEllipticCurveType:*] and pass in the int type;
  3. How to find the required curve, the three most common curves sm2p256v1, secp256k1, secp256r1 are listed in the GMSm2Utils header file enumeration;
  4. If it is another curve, you can find it in the OpenSSL source code crypto/ec/ec_curve.c and input the int type.

GMCurveType in GMSm2Utils.h file corresponds to curve parameters:

ECC recommended parameters: sm2p256v1 (corresponding to NID_sm2 in OpenSSL)
p   = FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF
a   = FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC
b   = 28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93
n   = FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123
Gx =  32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7
Gy =  BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0

ECC recommended parameters: secp256k1 (corresponding to NID_secp256k1 in OpenSSL)
p   = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
a   = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b   = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007
n   = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
Gx =  79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
Gy =  483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8

ECC recommended parameters: secp256r1 (corresponding to NID_X9_62_prime256v1 in OpenSSL)
p   = FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF
a   = FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFC
b   = 5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B
n   = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551
Gx  = 6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0 F4A13945 D898C296
Gy  = 4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE CBB64068 37BF51F5

Possible errors

The binary file was rejected due to signature review:

ITMS-91065: Missing signature - Your app includes “Frameworks/OpenSSL.framework/OpenSSL”, which includes BoringSSL / openssl_grpc, an SDK that was identified in the documentation as a privacy-impacting third-party SDK. If a new app includes a privacy-impacting SDK, or an app update adds a new privacy-impacting SDK, the SDK must include a signature file. Please contact the provider of the SDK that includes this file to get an updated SDK version with a signature.

Solution, manually sign the specified binary file, please refer to issues 92.

# Check the signature, no signature is displayed code object is not signed at all
codesign -dv --verbose=4 OpenSSL.xcframework
# Copy the certificate name in the keychain and execute this command to sign.
xcrun codesign --timestamp -s "full name of certificate" OpenSSL.xcframework
# Verify signature
xcrun codesign --verify --verbose OpenSSL.xcframework

Xcode compilation error 1:

Building for iOS, but the linked and embedded framework 'GMObjC.framework' was built for iOS + iOS Simulator.

Solution, select the project path Build Settings-Build Options-Validate Workspace and change it to YES/NO, and change it once.

Xcode compilation error 2:

building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Solution, select the project path Build Settings-Architectures-Excluded Architecture, select Any iOS Simulator SDK to add arm64, refer to stackoverflow solution.

Other

If you find it helpful, please give a Star ⭐️ on GitHub GMObjC, your encouragement is my motivation

gmobjc's People

Contributors

muzipiao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gmobjc's Issues

iOS使用secp256k1出现校验失败

单独使用demo里的testECDH,出现校验失败,加密算法用的k256k1EllipticCurveType
EC_GROUP *group = EC_GROUP_new_by_curve_name(k256k1EllipticCurveType); // 椭圆曲线

xcode pod GMObjc 打包出错

项目中 pod GMObjc 库后,在真机上 和模拟器上都正常运行,但是打包(Archive)后出错,

求问sm2加签验签

感谢muzipiao终于让我找到一个靠谱的国密oc库和demo。
但关于sm2的加签验签,这里有问题求问。
这边我们希望使用的是sm3withsm2(类似sha256withRSA),
demo里面的例子,我看到digest使用的是EVP_sm3。
这里我可否理解这个加签验签的事例其实就是 sm3withsm2?
我理解上有什么纰漏,也烦请指出。

新版本不支持armv7,引入工程后,可以模拟器运行,但是打包link报错怎么处理啊,报错日志如下

Undefined symbols for architecture armv7:
"OBJC_CLASS$_GMSm4Utils", referenced from:
objc-class-ref in URLSingleton.o
"OBJC_CLASS$_GMSm3Utils", referenced from:
objc-class-ref in URLSingleton.o
"OBJC_CLASS$_GMSm2Utils", referenced from:
objc-class-ref in URLSingleton.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

编译动态库,获取的framework无法使用

我在工程里的GMObjC.framework里command+b得到的framework时,使用sm2加密,加密出的都是nil,但是使用xcframework是可以使用sm2加密的。
由于我们的项目无法使用xcframwork,并且openssl版本冲突,只能使用framework。所以我该如何获得正确的framework呢

请教,后台提供key文件的公钥无法用于加密

后台提供.key文件的公钥,解析读取后,得到格式为
-----BEGIN PUBLIC KEY-----
MFkwEwYHK...(中间忽略)....QbJMgIT
PzAYl4qN...(中间忽略)....1JxIw+TXf/R9/jSkkkA==
-----END PUBLIC KEY-----
我把上下两端字符串按照教程传输进去:
NSArray *pubKey = @"MFkwEwYHK...(中间忽略)....QbJMgIT""PzAYl4qN...(中间忽略)....1JxIw+TXf/R9/jSkkkA==";
感觉格式明显对不上。
果然,加密@"123456"的结果返回为nil。
后来进行key的Hex编码处理:
NSString *keyHex = [GMUtils stringToHex:pubKey];
然而,加密@"123456"的结果依然返回为nil。
请问还要处理什么吗?

关于sm2keyexchange

最近和java同学联调,关于密钥协商这块,我用的ecdh,但java端亮出了SM2keyExchange的神秘算法,说是jce自带的。
乍一看和ecdhe还有点像,这块儿求教@muzipiao,openssl也提供类似的接口吗?

pod导入后 调用sm2加密 结果返回nil

你好,首先表达感谢,可以有这么好的工具用来使用国密相关加解密。
现在遇到问题,我在导入 GMObjc 后,使用sm2加密 ,返回结果为nil,通过断点调试,发现EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_sm2); // 椭圆曲线
返回结果 group 为null,但是我单独新建demo调试的时候,是可以加密成功的
不知道什么原因,请大神解惑

pod fail

pod search GMObjC
[!] Unable to find a pod with name, author, summary, or description matching GMObjC

pod install
Analyzing dependencies
[!] CocoaPods could not find compatible versions for pod "GMObjC":
In Podfile:
GMObjC (= 3.0.0)

None of your spec sources contain a spec satisfying the dependency: GMObjC (= 3.0.0).

You have either:

  • out-of-date source repos which you can update with pod repo update or with pod install --repo-update.
  • mistyped the name or version.
  • not added the source repo that hosts the Podspec to your Podfile.

Note: as of CocoaPods 1.0, pod repo update does not happen on pod install by default.

error read memory failed

1、百度地图6.0.0版本,解决OpenSSL冲突问题
2、GMObjC 3.1.2版本
集成以上两个SDK版本,运行程序直接报error read memory failed,请作者看一下什么原因

GMObjC.framework 动态库

将 GMObjC.framework 设置为 Embed & Sign,编译运行项目时,xcode提示Unable to install,将动态库删除后项目正常运行,希望大神给个解决方案。
xcode版本:12.3

SM4 ECB 模式解密时程序崩溃

16 进制编码
密文 410cc52868d787be3374dc9d27e37e26dc26dc7d2653883d615b0d1dd707325e
秘钥 D4E06ACBEC6240E78802E5A910CD9589
调用 GMSm4Utils + (nullable NSString *)ecbDecryptText:(NSString *)ciphertext key:(NSString *)key; 函数解密时程序奔溃了
麻烦帮忙看下, 万分感谢

Framework真机编译报错

因为pod后发现和现有项目百度地图sdk的ssl冲突,所以打算打成framework,但是真机编译报错

could not reparse object file in bitcode bundle: 'Invalid bitcode version (Producer: '1103.0.32.59.0_0' Reader: '1100.0.33.8_0')', using libLTO version 'LLVM version 11.0.0, (clang-1100.0.33.8)' for architecture arm64

模拟器编译可以成功

手动引入的时候,找不到sm2.h,sm3.h,sm4.h中的方法

因为某些原因,只能手动引入,不能使用cocopods。
我需要将您的GMObjC以及GMOppenSSL手动引入,并封装在我自己的SDK内, 手动引入后,编译打包成framework库没有问题,但是项目中引入这个framework库后,报找不到sm2.h,sm3.h,sm4.h中的方法。
路径配置都看了,是没有问题的。能帮忙看下是什么问题吗?
截屏2020-02-11下午1 24 17

pod运行项目直接崩溃

pod 'AFNetworking', '> 4.0.1'
pod 'SDWebImage', '
> 5.7.3'
pod 'SDWebImageWebPCoder'
pod 'Masonry', '> 1.1.0'
pod 'SDCycleScrollView', '
> 1.80'

MJRefresh

pod 'MJRefresh', '> 3.4.1'
pod 'BaiduMapKit', '
> 5.0.0'
pod 'BMKLocationKit', '> 1.8.0'
pod 'FMDB', '
> 2.7.5'
pod 'TZImagePickerController', '> 3.3.1'
pod 'Bugly', '
> 2.5.2'
pod 'MJExtension', '> 3.2.1'
pod 'IQKeyboardManager', '
> 6.5.5'
pod 'MBProgressHUD', '> 1.2.0'
pod 'VehicleKeyboard-swift'
pod 'UMCCommon'
pod 'UMCAnalytics'
pod 'XDCaptureService', '
> 1.2.1'
pod 'FTPopOverMenu', '1.3.2'
pod 'AMapLocation'
pod 'GMObjC','3.0.0'
source 'https://github.com/aliyun/aliyun-specs.git'
pod 'AliyunOSSiOS', '> 2.10.8'
pod 'AlicloudPush', '
> 1.9.9.1'
pod 'AlicloudCrash' , '~> 1.1.0'

我项目中存在这些三方,是存在冲突了吗?

openssl冲突

由于老项目用到RSA加密 依赖的库用到RSA_size等方法 我把GMObjC.framework在Link Binary With Libraries中拖到最后

编译运行的时候没问题 但是Archive的时候 打包没问题 运行还是报错

或者有无办法将RSA相关的方法干掉?

这个是不是Other Linker Flag -ObjC的功能 有无方法单独GMObjC.framework不添加-ObjC进行编译?

有空帮忙看看吗?谢谢!

java侧sm2验签失败

公、私钥、userID、椭圆曲线参数都一致,java端也对z项做了摘要,本地签名验签成功,服务端失败,什么原因

OpenSSL 冲突

作者你好,我这是和百度地图openssl冲突,按照你说的升级第三方opebsll库,然后公用一个可以解决。但是我这 和百度地图冲突,不是很明白要怎么和百度地图解决冲突。可以麻烦你指点一下吗?谢谢。我的QQ:1587557282. 如果可以,想加你qq详细了解一下。谢谢!

R+S加签

加签后的数据长度是固定的128位吗?

项目崩溃

你好,通过你说的编译后导入openssl.framework文件,然后手动导入GMObjC,正常情况下是没事的,但是当我们集成BaiduMapKit之后,会报错,请问这该怎样解决呢?QQ:1587557282。麻烦加我一下qq吧,有些问题想请教。

if (!EC_KEY_generate_key(key))
地方崩溃
Thread 1: EXC_BAD_ACCESS (code=2, address=0x106ccd3a0)

///MARK: - 创建公私钥对

+ (NSArray<NSString *> *)createKeyPair{
    NSArray<NSString *> *keyArray = @[@"", @""];
    EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_sm2); // 椭圆曲线
    EC_KEY *key = NULL; // 密钥对
    do {
        key = EC_KEY_new();
        if (!EC_KEY_set_group(key, group)) {
            break;
        }
        if (!EC_KEY_generate_key(key)) {
            break;
        }
        const EC_POINT *pub_key = EC_KEY_get0_public_key(key);
        const BIGNUM *pri_key = EC_KEY_get0_private_key(key);

        char *hex_pub = EC_POINT_point2hex(group, pub_key, EC_KEY_get_conv_form(key), NULL);
        char *hex_pri = BN_bn2hex(pri_key);
        
        NSString *pubHex = [NSString stringWithCString:hex_pub encoding:NSUTF8StringEncoding];
        NSString *priHex = [NSString stringWithCString:hex_pri encoding:NSUTF8StringEncoding];
        if (pubHex.length > 0 && priHex.length > 0) {
            NSString *priHexWithPadding = [self bnToHexPadding:priHex];
            keyArray = @[pubHex, priHexWithPadding];
        }
        OPENSSL_free(hex_pub);
        OPENSSL_free(hex_pri);
    } while (NO);
    
    if (group != NULL) EC_GROUP_free(group);
    EC_KEY_free(key);
    
    return keyArray;
}

missing required architecture armv7

ld: warning: ignoring file /Users/aiquantong/Documents/me/code/jianhua.git/code/Pods/GMOpenSSL/GMOpenSSL/openssl.framework/openssl, missing required architecture armv7 in file /Users/aiquantong/Documents/me/code/jianhua.git/code/Pods/GMOpenSSL/GMOpenSSL/openssl.framework/openssl (3 slices)

关于ECDHE的使用问题

你好
我在使用ECDHE过程中遇到一个问题:
我们使用的椭圆曲线是:

基于 ECC NIST P-256 曲线(即 secp256r1)进行计算,该曲线的参数详情见:https://www.secg.org/SEC2-
Ver-1.0.pdf
  
"secp256r1": {
"p": 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff,
"a": 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc,
"b": 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b,
"g": (0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,
0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5),
"n": 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551,
"h": 0x1 }

我修改了您的代码

EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp256k1); // 椭圆曲线
//我看着NID_secp256k1 很像 , 就替换了椭圆曲线, 

验证也是正确的.

但是我们有一个测试文档

    //A私钥85c888a8c5aaeba1f1a056a093ff874e3e01524f3571320680a13bdedab3db56
    //A公钥1c4ad6faf196e616c28832a540c78af8e0c3e4c6e27fcd82d479ae6497050db645c7debe0efc508e4f0d8a2fef5496c1174a4aa149e10cd5b2f02a5e7eb4faa6
    
    //B私钥1d9bec7294e2a7426acff1c48e69d2dc995d471d3fe045b1bc3fa21298813fc8
    //B公钥8d413fedaa2d0fd1036c27a3cc08e1776b951918513bbd5d8d22286ade63cfbccc4ae4bfcf69efb580409c056850429bbb6453227aa0fc0670c0f23c53593bee
    
    //结果
//59e7866e936b8f4f4bcca03fe7de81483ae78f9939cd8084a3bdca6f813dfd63762892918be716e7a169c717eb9dc3a92d777a47f2dcc620c0130f2906a18ac6

我现在把这个数据传到API里面,
计算秘钥的时候
int ret = ECDH_compute_key(ecdh_text, outlen, pub_point, key, 0);
ret = 0;

我这边给的ECDHE文档.zip
结合我这边的数据, 在demo里面计算秘钥失败.
能帮忙看下是什么原因吗?
如果可以, 希望能得到您的帮助.

SM4加密后结果为null

NSString *sm4Key = @"8888888888888888";
NSString *plaintext = @"{"idserial":"123456"}";
NSString *ecbCipertext = [GMSm4Utils ecbEncryptText:plaintext key:sm4Key];
NSLog(@"打印SM4加密:%@", ecbCipertext);

image

你好,请教关于证书读取出现的问题

你好,多有打搅,请多见谅。
我读取.key文件的公钥,解析读取后,得到格式为
-----BEGIN PUBLIC KEY-----
MFkwEwYHK...(中间忽略)....QbJMgIT
PzAYl4qN...(中间忽略)....1JxIw+TXf/R9/jSkkkA==
-----END PUBLIC KEY-----
但是安卓读取.key文件的公钥得到:
EC Public Key [6c:37:39:4e:bd:...(中间忽略)....2:9b:3d:37:4d:5d:b0:93:db]
X: 8f6432e54a5c...(中间忽略)....18978e2a34f873d1ad
Y: 163f98a462fd...(中间忽略)....35dffd1f7f8d292490
我使用安卓的XY两字符串的公钥加04开头,完全没问题,所以应该是我读取.key文件有问题,所以我想请教应该怎么获取安卓这种格式的公钥,非常感谢。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.