简体   繁体   English

RSA SHA256登录iOS并在Java上进行验证

[英]RSA SHA256 signing in iOS and verification on Java

  1. I generated an RSA key pair with SecKeyGeneratePair. 我使用SecKeyGeneratePair生成了RSA密钥对。 The key size in bits is 2048. 密钥大小(以位为单位)为2048。

     NSDictionary *privateAttributes = @{(NSString *)kSecAttrIsPermanent: @YES, (NSString *)kSecAttrApplicationTag: PrivTag}; NSDictionary *publicAttributes = @{(NSString *)kSecAttrIsPermanent: @YES, (NSString *)kSecAttrApplicationTag: PubTag}; NSDictionary *pairAttributes = @{(NSString *)kSecAttrKeyType: (NSString *)kSecAttrKeyTypeRSA, (NSString *)kSecAttrKeySizeInBits: @2048, (NSString *)kSecPublicKeyAttrs: publicAttributes, (NSString *)kSecPrivateKeyAttrs: privateAttributes}; SecKeyRef publicKeyRef; SecKeyRef privateKeyRef; OSStatus osStatus = SecKeyGeneratePair((CFDictionaryRef)pairAttributes, &publicKeyRef, &privateKeyRef); switch (osStatus) { case noErr: break; default: break; } 
  2. Create the X.509 format of the public key and send it to the server. 创建公钥的X.509格式,并将其发送到服务器。

  3. Create the SHA256 digest of the custom string with CC_SHA256. 使用CC_SHA256创建自定义字符串的SHA256摘要。

     NSMutableData *hash = [NSMutableData dataWithLength:(NSUInteger)CC_SHA256_DIGEST_LENGTH]; NSData *data = [stringToSign dataUsingEncoding:NSUTF8StringEncoding]; CC_SHA256(data.bytes, (CC_LONG)data.length, hash.mutableBytes); 
  4. Sign the string with SecKeyRawSign method using kSecPaddingPKCS1SHA256. 使用kSecPaddingPKCS1SHA256使用SecKeyRawSign方法对字符串进行签名。

     // Sign the hash with the private key size_t blockSize = SecKeyGetBlockSize(privateKeyRef); NSUInteger hashDataLength = hash.length; const unsigned char *hashData = (const unsigned char *)hash.bytes; NSMutableData *result = [NSMutableData dataWithLength:blockSize]; uint8_t *signedHashBytes = malloc(blockSize * sizeof(uint8_t)); memset((void *) signedHashBytes, 0x0, blockSize); size_t encryptedDataLength = blockSize; OSStatus status = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1SHA256, hashData, hashDataLength, signedHashBytes, &encryptedDataLength); NSData *signedHash = [NSData dataWithBytes:(const void *) signedHashBytes length:(NSUInteger) encryptedDataLength]; 
  5. Apply base64 on the signed data and send it to the server. 在签名的数据上应用base64并将其发送到服务器。

  6. The java server cannot verify it with the public key. Java服务器无法使用公共密钥对其进行验证。

I have the same above code in Swift. 我在Swift中有相同的上述代码。 As a debug step, I've exported my private key too and tried to follow the exact same steps in java. 作为调试步骤,我也导出了私钥,并尝试遵循Java中完全相同的步骤。 Until step 3 everything is the same. 在步骤3之前,所有操作都是相同的。 So, the iOS creates the same digest as the java app. 因此,iOS创建与Java应用程序相同的摘要。 The fourth step, the signing creates a different output than the java code. 第四步,签名创建与Java代码不同的输出。

Here's the java code: 这是Java代码:

final Signature instance = Signature.getInstance("SHA256withRSA");
instance.initSign(privateKey);
instance.update(MessageDigest.getInstance("SHA-256").digest(rawString.toString().getBytes("UTF-8")));

Digital signature API for iOS and Java is different but the result is the same. iOS和Java的数字签名API不同,但结果相同。

iOS SecKeyRawSign with kSecPaddingPKCS1SHA256 uses a SHA256 digest, but in Java Signature.sign requires the raw data and it makes digest+pkcs1. 带有kSecPaddingPKCS1SHA256 iOS SecKeyRawSign使用SHA256摘要,但是在Java Signature.signkSecPaddingPKCS1SHA256需要原始数据,并且使摘要+ pkcs1。 Use 采用

instance.update(rawString.toString().getBytes("UTF-8"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM