RSA SHA256登录iOS并在Java上进行验证 [英] RSA SHA256 signing in iOS and verification on Java

查看:487
本文介绍了RSA SHA256登录iOS并在Java上进行验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 我用SecKeyGeneratePair生成了一个RSA密钥对.密钥大小(以位为单位)为2048.

  1. I generated an RSA key pair with SecKeyGeneratePair. The key size in bits is 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;
}

  • 创建公钥的X.509格式并将其发送到服务器.

  • Create the X.509 format of the public key and send it to the server.

    使用CC_SHA256创建自定义字符串的SHA256摘要.

    Create the SHA256 digest of the custom string with CC_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);
    

  • 使用kSecPaddingPKCS1SHA256的SecKeyRawSign方法对字符串进行签名.

  • Sign the string with SecKeyRawSign method using kSecPaddingPKCS1SHA256.

    // 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];
    

  • 在签名的数据上应用base64并将其发送到服务器.

  • Apply base64 on the signed data and send it to the server.

    我在Swift中有相同的上述代码. 作为调试步骤,我也导出了我的私钥,并尝试遵循Java中完全相同的步骤.在第3步之前,所有操作都是相同的.因此,iOS创建与Java应用程序相同的摘要.第四步,签名创建与Java代码不同的输出.

    I have the same above code in Swift. As a debug step, I've exported my private key too and tried to follow the exact same steps in java. Until step 3 everything is the same. So, the iOS creates the same digest as the java app. The fourth step, the signing creates a different output than 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")));
    

    推荐答案

    iOS和Java的数字签名API不同,但结果相同.

    Digital signature API for iOS and Java is different but the result is the same.

    iOS SecKeyRawSign使用SHA256摘要,但是在Java中,Signature.sign需要原始数据,并且使摘要+ pkcs1.使用

    iOS SecKeyRawSign with kSecPaddingPKCS1SHA256 uses a SHA256 digest, but in Java Signature.sign requires the raw data and it makes digest+pkcs1. Use

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

    这篇关于RSA SHA256登录iOS并在Java上进行验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆