數(shù)字簽名----sha1withrsa

項目中進行了sha1withrsa數(shù)字簽名利诺。對此總結(jié)一下吧涌哲。

淺談加密與簽名

我們一般的加密主要分2種胖缤。對稱加密。非對稱加密阀圾。顧名思義哪廓。對稱加密就是秘鑰是一樣的。通過同一個秘鑰加密解密初烘。這一類的加密算法有DES,3DES撩独,AES等。而非對稱加密即使用公鑰和秘鑰2個账月。公鑰進行加密综膀,而私鑰進行解密。這一類的加密算法主要RSA

數(shù)字簽名并不是加密局齿。他只是將傳遞的參數(shù)進行簽名剧劝。服務(wù)器端可以驗簽。主要作用有2個:1.保證數(shù)據(jù)不會被篡改抓歼。2.保證請求的確是秘鑰持有者發(fā)送的讥此。 雖然他不是加密但是這里我們使用到了RSA加密。sha1withrsa顧名思義谣妻。是將加密對象進行sha1后進行rsa加密萄喳。當(dāng)然。并不是簡單的sha1后就直接rsa蹋半。中間有一些處理他巨。具體的細節(jié)我不是很了解。也不需要了解除非你對算法極度感興趣∪就唬可以去找找資料弄明白捻爷。不管怎樣處理。最后我們得到了用rsa秘鑰加密后的數(shù)據(jù)份企。一般情況下我們會base64成一個字符串也榄,方便傳輸。這樣的字符串就是數(shù)字簽名了司志。服務(wù)器端只需要用對應(yīng)的公鑰進行驗簽就可以判斷出是不是秘鑰持有者發(fā)送的消息了甜紫。

淺談rsa秘鑰公鑰以及pkcs1,pkcs8格式

首先推薦一個在線生成秘鑰公鑰以及加密解密的網(wǎng)站http://tool.chacuo.net/cryptrsapubkey

自己生成公鑰秘鑰一般情況下就需要使用openssl工具了骂远。使用工具執(zhí)行命令

genrsa -out rsa_private_key.pem 2048

2048指的是位數(shù)囚霸。一般情況下1024也夠用了。如果要求高點還是2048位更加合適點吧史。生成的pem文件里面以-----BEGIN RSA PRIVATE KEY-----開頭-----END RSA PRIVATE KEY-----結(jié)尾的字符串。中間的部分才是秘鑰的base64字符串.這個是pkcs1格式的唠雕。也就是原本的rsa密鑰贸营。

rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

上面的命令會根據(jù)剛剛的私鑰生成pkcs8格式的公鑰。

如果需要pkcs8個格式的私鑰(java就是用pkcs8格式的)需要

pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

會打印出來以-----BEGIN PRIVATE KEY-----開頭岩睁。以-----END PRIVATE KEY-----結(jié)尾的私鑰钞脂。

這里我們需要了解一下pkcs1格式和pkcs8格式的區(qū)別和關(guān)聯(lián):

pkcs1的格式才是原本的rsa的密鑰。而pkcs8的格式是在pkcs1的數(shù)據(jù)上增加一些信息捕儒。具體這些信息是什么我并沒有去深入了解冰啃。我們只需要知道pkcs1和pkcs8之間是可以轉(zhuǎn)換的。以2048位的為例:

公鑰 pkcs8 轉(zhuǎn)換為 pkcs1 其實就是將前面的32位去除即可

私鑰的轉(zhuǎn)換需要使用openssl

pkcs8轉(zhuǎn)rsa:

openssl rsa -in pkcs8密鑰 -out rsa密鑰

rsa轉(zhuǎn)pkcs8:

openssl pkcs8 -topk8 -inform PEM -in rsa密鑰 -outform PEM -nocrypt -out pkcs8密鑰

而在iOS端可能需要生成p12文件刘莹。

1. 生成模長為1024bit的私鑰文件private_key.pem

openssl genrsa -out private_key.pem 1024

2. 生成證書請求文件rsaCertReq.csr

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

注意:這一步會提示輸入國家阎毅、省份、mail等信息点弯,可以根據(jù)實際情況填寫扇调,或者全部不用填寫,直接全部敲回車.

3. 生成證書rsaCert.crt抢肛,并設(shè)置有效時間為1年

openssl x509 -req -days 3650 -in rsaCerReq.csr -signkey private_key.pem -out rsaCert.crt

4. 生成供iOS使用的公鑰文件public_key.der

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

5. 生成供iOS使用的私鑰文件private_key.p12

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

注意:這一步會提示給私鑰文件設(shè)置密碼狼钮,直接輸入想要設(shè)置密碼即可,然后敲回車捡絮,然后再驗證剛才設(shè)置的密碼熬芜,再次輸入密碼,然后敲回車福稳,完畢涎拉!

在解密時,private_key.p12文件需要和這里設(shè)置的密碼配合使用,因此需要牢記此密碼.

關(guān)于數(shù)字簽名的java曼库,iOS 区岗,以及 lua(使用openresty)的實現(xiàn)

java使用的是pkcs8格式。這個需要知道毁枯。接下來的我就直接貼代碼吧:

public static boolean rsaCheckContent(String content, String sign, String publicKey,

String charset) throws Exception {

try {

PublicKey pubKey = getPublicKeyFromX509("RSA",

new ByteArrayInputStream(publicKey.getBytes()));

java.security.Signature signature = java.security.Signature

.getInstance(Constants.SIGN_ALGORITHMS);//"SHA1WithRSA"

signature.initVerify(pubKey);

if (StringUtils.isEmpty(charset)) {

signature.update(content.getBytes());

} else {

signature.update(content.getBytes(charset));

}

byte[] d =? Base64.decode(sign.getBytes());

return signature.verify(d);

} catch (Exception e) {

return false;

//throw new Exception("RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);

}

}

publicstaticPublicKey getPublicKeyFromX509(Stringalgorithm,

InputStreamins)throwsException {

KeyFactorykeyFactory= KeyFactory.getInstance(algorithm);

StringWriterwriter=newStringWriter();

StreamUtil.io(newInputStreamReader(ins),writer);

byte[]encodedKey=writer.toString().getBytes();

encodedKey= Base64.decode(encodedKey);

returnkeyFactory.generatePublic(newX509EncodedKeySpec(encodedKey));

}


ios的代碼如下--

#define kChosenDigestLength CC_SHA1_DIGEST_LENGTH

- (NSData*)getHashBytes:(NSData*)plainText {

CC_SHA1_CTXctx;

uint8_t* hashBytes =NULL;

NSData* hash =nil;

// Malloc a buffer to hold hash.

hashBytes =malloc(kChosenDigestLength*sizeof(uint8_t) );

memset((void*)hashBytes,0x0,kChosenDigestLength);

// Initialize the context.

CC_SHA1_Init(&ctx);

// Perform the hash.

CC_SHA1_Update(&ctx, (void*)[plainTextbytes], (CC_LONG)[plainTextlength]);

// Finalize the output.

CC_SHA1_Final(hashBytes, &ctx);

// Build up the SHA1 blob.

hash = [NSDatadataWithBytes:(constvoid*)hashByteslength:(NSUInteger)kChosenDigestLength];

if(hashBytes)free(hashBytes);

returnhash;

}

-(NSString*)signTheDataSHA1WithRSA:(NSString*)plainText

{

uint8_t* signedBytes =NULL;

size_tsignedBytesSize =0;

OSStatussanityCheck =noErr;

NSData* signedHash =nil;

NSString* path = [[NSBundlemainBundle]pathForResource:@"privateKey"ofType:@"p12"];

NSData* data = [NSDatadataWithContentsOfFile:path];

NSMutableDictionary* options = [[NSMutableDictionaryalloc]init];// Set the private key query dictionary.

[optionssetObject:@"123456"forKey:(id)kSecImportExportPassphrase];

CFArrayRefitems =CFArrayCreate(NULL,0,0,NULL);

OSStatussecurityError =SecPKCS12Import((CFDataRef) data, (CFDictionaryRef)options, &items);

if(securityError!=noErr) {

returnnil;

}

CFDictionaryRefidentityDict =CFArrayGetValueAtIndex(items,0);

SecIdentityRefidentityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);

SecKeyRefprivateKeyRef=nil;

SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);

signedBytesSize =SecKeyGetBlockSize(privateKeyRef);

NSData*plainTextBytes = [plainTextdataUsingEncoding:NSUTF8StringEncoding];

signedBytes =malloc( signedBytesSize *sizeof(uint8_t) );// Malloc a buffer to hold signature.

memset((void*)signedBytes,0x0, signedBytesSize);

sanityCheck =SecKeyRawSign(privateKeyRef,

kSecPaddingPKCS1SHA1,

(constuint8_t*)[[selfgetHashBytes:plainTextBytes]bytes],

kChosenDigestLength,

(uint8_t*)signedBytes,

&signedBytesSize);

if(sanityCheck ==noErr)

{

signedHash = [NSDatadataWithBytes:(constvoid*)signedByteslength:(NSUInteger)signedBytesSize];

}

else

{

returnnil;

}

if(signedBytes)

{

free(signedBytes);

}

NSString*signatureResult = [[NSStringalloc]initWithData:[signedHashbase64EncodedDataWithOptions:0]encoding:NSASCIIStringEncoding];

returnsignatureResult;

}



我一開始打算服務(wù)器使用java驗簽慈缔。可是發(fā)現(xiàn)nginx-lua 模塊有

https://github.com/doujiang24/lua-resty-rsa

使用這個效果不錯哦种玛。不過需要注意的是他使用的是pkcs1的格式

主要代碼如下:

local resty_rsa = require "resty.rsa"

local priv, err = resty_rsa:new({ private_key = RSA_PRIV_KEY })

local algorithm = "SHA1"

local pub, err = resty_rsa:new({ public_key = RSA_PUBLIC_KEY, algorithm = algorithm })

if not pub then

ngx.say("new rsa err: ", err)

return

end

local serverSign = ngx.decode_base64(signStr)

local verify, err = pub:verify(stringForSign,serverSign)

if(verify) then

ngx.exec("@appBack")

else

ngx.say("簽名不正確")

end

好了就記錄這些吧藐鹤。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赂韵,一起剝皮案震驚了整個濱河市娱节,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祭示,老刑警劉巖肄满,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異质涛,居然都是意外死亡稠歉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門汇陆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怒炸,“玉大人,你說我怎么就攤上這事毡代≡母” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵教寂,是天一觀的道長捏鱼。 經(jīng)常有香客問我,道長酪耕,這世上最難降的妖魔是什么穷躁? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮因妇,結(jié)果婚禮上问潭,老公的妹妹穿的比我還像新娘。我一直安慰自己婚被,他們只是感情好狡忙,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著址芯,像睡著了一般灾茁。 火紅的嫁衣襯著肌膚如雪窜觉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天北专,我揣著相機與錄音禀挫,去河邊找鬼。 笑死拓颓,一個胖子當(dāng)著我的面吹牛语婴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播驶睦,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼砰左,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了场航?” 一聲冷哼從身側(cè)響起缠导,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎溉痢,沒想到半個月后僻造,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡孩饼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年髓削,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捣辆。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蔬螟,死狀恐怖此迅,靈堂內(nèi)的尸體忽然破棺而出汽畴,到底是詐尸還是另有隱情,我是刑警寧澤耸序,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布忍些,位于F島的核電站,受9級特大地震影響坎怪,放射性物質(zhì)發(fā)生泄漏罢坝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一搅窿、第九天 我趴在偏房一處隱蔽的房頂上張望嘁酿。 院中可真熱鬧,春花似錦男应、人聲如沸闹司。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽游桩。三九已至牲迫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間借卧,已是汗流浹背盹憎。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铐刘,地道東北人陪每。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像滨达,于是被迫代替她去往敵國和親奶稠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容