日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

ios rsa java_一篇搞定RSA加密与SHA签名|与Java完全同步

發布時間:2024/9/30 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios rsa java_一篇搞定RSA加密与SHA签名|与Java完全同步 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文是投稿文章,作者:Panda_iOS

看到這篇文章的同學可幸福了,當時在做RSA加密與簽名的時候網上的資料簡直不要太老,做完后實在是忍受不下去了,這篇文章我會詳細講解iOS如何實現RSA加密與簽名,并且與Java完全同步,這是我的第二篇博客,若有什么不足之處還請大家指教。

基礎知識

什么是RSA?

答:RSA是一種非對稱加密算法,常用來對傳輸數據進行加密,配合上數字摘要算法,也可以進行文字簽名。

RSA加密中padding?

答:padding即填充方式,由于RSA加密算法中要加密的明文是要比模數小的,padding就是通過一些填充方式來限制明文的長度。后面會詳細介紹padding的幾種模式以及分段加密。

加密和加簽有什么區別?

答:加密:公鑰放在客戶端,并使用公鑰對數據進行加密,服務端拿到數據后用私鑰進行解密。

加簽:私鑰放在客戶端,并使用私鑰對數據進行加簽,服務端拿到數據后用公鑰進行驗簽。

前者完全為了加密;后者主要是為了防惡意攻擊,防止別人模擬我們的客戶端對我們的服務器進行攻擊,導致服務器癱瘓。

基本原理

RSA使用“密鑰對”對數據進行加密解密,在加密解密前需要先生存公鑰(Public Key)和私鑰(Private Key)。

公鑰(Public key):?用于加密數據. 用于公開, 一般存放在數據提供方, 例如iOS客戶端。

私鑰(Private key):?用于解密數據. 必須保密, 私鑰泄露會造成安全問題。

iOS中的Security.framework提供了對RSA算法的支持,這種方式需要對密匙對進行處理, 根據public key生成證書, 通過private key生成p12格式的密匙。想想jave直接用字符串進行加密解密簡單多了。(⊙o⊙)…

實戰

證書生成RSA加密這塊公鑰、私鑰必不可少的。Apple是不支持直接使用字符串進行加密解密的,推薦使用p12文件。這邊教大家去生成在加密中使用到的所有文件,并提供給Java使用,想當年這個公鑰私鑰搞了半天了。 %>_

生成模長為1024bit的私鑰

openssl genrsa -out private_key.pem 1024

生成certification require file

openssl req -new -key private_key.pem -out rsaCertReq.csr

生成certification 并指定過期時間

openssl x509 -req -days3650-in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

生成公鑰供iOS使用

openssl x509 -outform der -in rsaCert.crt -out public_key.der

生成私鑰供iOS使用 這邊會讓你輸入密碼,后期用到在生成secKeyRef的時候會用到這個密碼

openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

生成pem結尾的公鑰供Java使用

openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout

生成pem結尾的私鑰供Java使用openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt

以上所有的步驟都是在終端下完成的哦 (^__^)

生成公鑰和私鑰的secKeyRef

//根據你的p12文件生成私鑰對應的SecKeyRef?這邊返回若是nil?請檢查你p12文件的生成步驟

-?(SecKeyRef)getPrivateKeyRefrenceFromData:(NSData*)p12Data?password:(NSString*)password?{

SecKeyRef?privateKeyRef?=?NULL;

NSMutableDictionary?*?options?=?[[NSMutableDictionary?alloc]?init];

[options?setObject:?password?forKey:(__bridge?id)kSecImportExportPassphrase];

CFArrayRef?items?=?CFArrayCreate(NULL,?0,?0,?NULL);

OSStatus?securityError?=?SecPKCS12Import((__bridge?CFDataRef)?p12Data,?(__bridge?CFDictionaryRef)options,?&items);

if?(securityError?==?noErr?&&?CFArrayGetCount(items)?>?0)?{

CFDictionaryRef?identityDict?=?CFArrayGetValueAtIndex(items,?0);

SecIdentityRef?identityApp?=?(SecIdentityRef)CFDictionaryGetValue(identityDict,?kSecImportItemIdentity);

securityError?=?SecIdentityCopyPrivateKey(identityApp,?&privateKeyRef);

if?(securityError?!=?noErr)?{

privateKeyRef?=?NULL;

}

}

CFRelease(items);

return?privateKeyRef;

}

-//根據你的der文件公鑰對應的SecKeyRef

-?(SecKeyRef)getPublicKeyRefrenceFromeData:????(NSData*)derData?{

SecCertificateRef?myCertificate?=?SecCertificateCreateWithData(kCFAllocatorDefault,?(__bridge?CFDataRef)derData);

SecPolicyRef?myPolicy?=?SecPolicyCreateBasicX509();

SecTrustRef?myTrust;

OSStatus?status?=?SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);

SecTrustResultType?trustResult;

if?(status?==?noErr)?{

status?=?SecTrustEvaluate(myTrust,?&trustResult);

}

SecKeyRef?securityKey?=?SecTrustCopyPublicKey(myTrust);

CFRelease(myCertificate);

CFRelease(myPolicy);

CFRelease(myTrust);

return?securityKey;

}

加密與解密

-?(NSData*)rsaEncryptData:(NSData*)data?{

SecKeyRef?key?=?[self?getPublicKey];

size_t?cipherBufferSize?=?SecKeyGetBlockSize(key);

uint8_t?*cipherBuffer?=?malloc(cipherBufferSize?*?sizeof(uint8_t));

size_t?blockSize?=?cipherBufferSize?-?11;

size_t?blockCount?=?(size_t)ceil([data?length]?/?(double)blockSize);

NSMutableData?*encryptedData?=?[[NSMutableData?alloc]?init];

for?(int?i=0;?i

unsigned?long?bufferSize?=?MIN(blockSize?,?[data?length]?-?i?*?blockSize);

NSData?*buffer?=?[data?subdataWithRange:NSMakeRange(i?*?blockSize,?bufferSize)];

OSStatus?status?=?SecKeyEncrypt(key,?kSecPaddingPKCS1,?(const?uint8_t?*)[buffer?bytes],?[buffer?length],?cipherBuffer,?&cipherBufferSize);

if?(status?!=?noErr)?{

return?nil;

}

NSData?*encryptedBytes?=?[[NSData?alloc]?initWithBytes:(const?void?*)cipherBuffer?length:cipherBufferSize];

[encryptedData?appendData:encryptedBytes];

}

if?(cipherBuffer){

free(cipherBuffer);

}

return?encryptedData;

}

-

-?(NSData*)rsaDecryptData:(NSData*)data?{

SecKeyRef?key?=?[self?getPrivatKey];

size_t?cipherBufferSize?=?SecKeyGetBlockSize(key);

size_t?blockSize?=?cipherBufferSize;

size_t?blockCount?=?(size_t)ceil([data?length]?/?(double)blockSize);

NSMutableData?*decryptedData?=?[[NSMutableData?alloc]?init];

for?(int?i?=?0;?i?

unsigned?long?bufferSize?=?MIN(blockSize?,?[data?length]?-?i?*?blockSize);

NSData?*buffer?=?[data?subdataWithRange:NSMakeRange(i?*?blockSize,?bufferSize)];

size_t?cipherLen?=?[buffer?length];

void?*cipher?=?malloc(cipherLen);

[buffer?getBytes:cipher?length:cipherLen];

size_t?plainLen?=?SecKeyGetBlockSize(key);

void?*plain?=?malloc(plainLen);

OSStatus?status?=?SecKeyDecrypt(key,?kSecPaddingPKCS1,?cipher,?cipherLen,?plain,?&plainLen);

if?(status?!=?noErr)?{

return?nil;

}

NSData?*decryptedBytes?=?[[NSData?alloc]?initWithBytes:(const?void?*)plain?length:plainLen];

[decryptedData?appendData:decryptedBytes];

}

return?decryptedData;

}

RSA加密中的Padding

RSA_PKCS1_PADDING 填充模式,最常用的模式

要求: 輸入:必須 比 RSA 鑰模長(modulus) 短至少11個字節, 也就是 RSA_size(rsa) – 11 如果輸入的明文過長,必須切割,然后填充。

輸出:和modulus一樣長

根據這個要求,對于1024bit的密鑰,block length = 1024/8 – 11 = 117 字節

RSA_PKCS1_OAEP_PADDING

輸入:RSA_size(rsa) – 41

輸出:和modulus一樣長

RSA_NO_PADDING  不填充

輸入:可以和RSA鑰模長一樣長,如果輸入的明文過長,必須切割, 然后填充

輸出:和modulus一樣長

簽名與驗證

//對數據進行sha256簽名

-?(NSData?*)rsaSHA256SignData:(NSData?*)plainData?{

SecKeyRef?key?=?[self?getPrivatKey];

size_t?signedHashBytesSize?=?SecKeyGetBlockSize(key);

uint8_t*?signedHashBytes?=?malloc(signedHashBytesSize);

memset(signedHashBytes,?0x0,?signedHashBytesSize);

size_t?hashBytesSize?=?CC_SHA256_DIGEST_LENGTH;

uint8_t*?hashBytes?=?malloc(hashBytesSize);

if?(!CC_SHA256([plainData?bytes],?(CC_LONG)[plainData?length],?hashBytes))?{

return?nil;

}

SecKeyRawSign(key,

kSecPaddingPKCS1SHA256,

hashBytes,

hashBytesSize,

signedHashBytes,

&signedHashBytesSize);

NSData*?signedHash?=?[NSData?dataWithBytes:signedHashBytes

length:(NSUInteger)signedHashBytesSize];

if?(hashBytes)

free(hashBytes);

if?(signedHashBytes)

free(signedHashBytes);

return?signedHash;

}

-//這邊對簽名的數據進行驗證?驗簽成功,則返回YES

-?(BOOL)rsaSHA256VerifyData:(NSData?*)plainData?????withSignature:(NSData?*)signature?{

SecKeyRef?key?=?[self?getPublicKey];

size_t?signedHashBytesSize?=?SecKeyGetBlockSize(key);

const?void*?signedHashBytes?=?[signature?bytes];

size_t?hashBytesSize?=?CC_SHA256_DIGEST_LENGTH;

uint8_t*?hashBytes?=?malloc(hashBytesSize);

if?(!CC_SHA256([plainData?bytes],?(CC_LONG)[plainData?length],?hashBytes))?{

return?NO;

}

OSStatus?status?=?SecKeyRawVerify(key,

kSecPaddingPKCS1SHA256,

hashBytes,

hashBytesSize,

signedHashBytes,

signedHashBytesSize);

return?status?==?errSecSuccess;

}

文章到此就結束了,希望這篇文章對大家有所幫助。想看demo的請點擊:XYRSACryptor

總結

以上是生活随笔為你收集整理的ios rsa java_一篇搞定RSA加密与SHA签名|与Java完全同步的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。