ios java rsa,RSA SHA256登录iOS并在Java上进行验证

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;

}

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

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);

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

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

The java server cannot verify it with the public key.

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.

Here's the java code:

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 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"));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值