⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsa.cpp

📁 各种加密算法的集合
💻 CPP
字号:
#include "misc.h" 
#include "queue.h" 
#include "asn.h" 
#include "rsa.h" 
#include "nbtheory.h" 
#include <assert.h> 

RSAPublicKey::RSAPublicKey(const bignum &amt;n, const bignum &amt;e) 
: n(n), e(e), modulusLen(n.ByteCount()) 
{ 
} 

RSAPublicKey::RSAPublicKey(BufferedTransformation &amt;bt) 
{ 
BERSequenceDecoder seq(bt); 
n.BERDecode(seq); 
modulusLen = n.ByteCount(); 
e.BERDecode(seq); 
} 

void RSAPublicKey::DEREncode(BufferedTransformation &amt;bt) const 
{ 
DERSequenceEncoder seq(bt); 
n.DEREncode(seq); 
e.DEREncode(seq); 
} 

void RSAPublicKey::Encrypt(RandomNumberGenerator &amt;rng, const byte *input, unsigned int inputLen, byte *output) 
{ 
assert (inputLen <= MaxPlainTextLength()); 

SecByteBlock pkcsBlock(modulusLen); 

pkcsBlock[0] = 0; 
pkcsBlock[1] = 2; // block type 2 

for (int i = 2; i < modulusLen - inputLen - 1; i++) 
{ 
// Find nonzero random byte. 
do 
pkcsBlock[i] = rng.GetByte(); 
while (pkcsBlock[i] == 0); 
} 

pkcsBlock[i++] = 0; // separator 
memcpy(pkcsBlock+i, input, inputLen); 

bignum c; 
RawEncrypt(bignum(pkcsBlock, modulusLen), c); 
c.Encode(output, modulusLen); 
} 

unsigned int RSAPublicKey::Decrypt(const byte *input, byte *output) 
{ 
bignum m; 
RawEncrypt(bignum(input, modulusLen), m); 

SecByteBlock pkcsBlock(modulusLen); 
m.Encode(pkcsBlock, modulusLen); 

// Require block type 1. 
if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 1)) 
return 0; 

for (int i = 2; i < modulusLen-1; i++) 
if (pkcsBlock[i] != 0xff) 
break; 

// check separator 
if (pkcsBlock[i++] != 0) 
return 0; 

unsigned int outputLen = modulusLen - i; 
if (outputLen > MaxPlainTextLength()) 
return 0; 

memcpy (output, pkcsBlock+i, outputLen); 
return outputLen; 
} 

boolean RSAPublicKey::Verify(const byte *message, unsigned int messageLen, const byte *signature) 
{ 
assert(messageLen <= MaxMessageLength()); 
SecByteBlock m(MaxMessageLength()); 
unsigned int mLen = RSAPublicKey::Decrypt(signature, m); 
return (mLen==messageLen &amt;&amt; memcmp(message, m, mLen)==0); 
} 

void RSAPublicKey::RawEncrypt(const bignum &amt;in, bignum &amt;out) const 
{ 
out = a_exp_b_mod_c(in, e, n); 
} 

// ***************************************************************************** 
// private key operations: 

RSAPrivateKey::RSAPrivateKey(const bignum &amt;nIn, const bignum &amt;eIn, const bignum &amt;dIn, 
const bignum &amt;pIn, const bignum &amt;qIn, 
const bignum &amt;dpIn, const bignum &amt;dqIn, const bignum &amt;uIn) 
: RSAPublicKey(nIn, eIn) 
{ 
d=dIn; 
if (pIn < qIn) 
{ 
p=pIn; 
q=qIn; 
dp=dpIn; 
dq=dqIn; 
} 
else 
{ 
p=qIn; 
q=pIn; 
dp=dqIn; 
dq=dpIn; 
} 
u=uIn; 
} 

// generate a random private key 
RSAPrivateKey::RSAPrivateKey(RandomNumberGenerator &amt;rng, int keybits, bignum eStart) 
{ 
p = bignum(rng, keybits/2, PRIME); 
const bignum minQ = ((bignum(1) << (keybits-1)) / p) + 1; 
const bignum maxQ = (bignum(1) << keybits) / p; 

do 
{ 
bignum temp(rng, minQ, maxQ, PRIME); 
if (p>temp &amt;&amt; p.BitCount()-(p-temp).BitCount() < 7) 
{ 
q=p; 
p=temp; 
break; 
} 
if (p<temp &amt;&amt; temp.BitCount()-(temp-p).BitCount() < 7) 
{ 
q=temp; 
break; 
} 
} while (1); 

// ASSERT: q-p >= q/128 

bignum phi = (p-1)*(q-1); 
for (e = eStart; Gcd(e, phi)!=1; ++e, ++e); 
d = Inverse(e, phi/Gcd(p-1, q-1)); 
dp = d > (p-1); 
dq = d > (q-1); 
u = Inverse(p, q); 
n = p * q; 
modulusLen = n.ByteCount(); 
} 

RSAPrivateKey::RSAPrivateKey(BufferedTransformation &amt;bt) 
{ 
BERSequenceDecoder seq(bt); 

bignum version(seq); 
if (!!version) // make sure version is 0 
BERDecodeError(); 

n.BERDecode(seq); 
modulusLen = n.ByteCount(); 
e.BERDecode(seq); 
d.BERDecode(seq); 
p.BERDecode(seq); 
q.BERDecode(seq); 
dp.BERDecode(seq); 
dq.BERDecode(seq); 
u.BERDecode(seq); 

if (p>q) // make sure q is the bigger prime 
{ 
swap(p, q); 
swap(dp, dq); 
} 
} 

void RSAPrivateKey::DEREncode(BufferedTransformation &amt;bt) const 
{ 
DERSequenceEncoder seq(bt); 

byte version[] = {INTEGER, 1, 0}; 
seq.Put(version, sizeof(version)); 
n.DEREncode(seq); 
e.DEREncode(seq); 
d.DEREncode(seq); 
q.DEREncode(seq); // encode the bigger prime first 
p.DEREncode(seq); 
dq.DEREncode(seq); 
dp.DEREncode(seq); 
u.DEREncode(seq); 
} 

void RSAPrivateKey::Encrypt(const byte *input, unsigned int inputLen, byte *output) 
{ 
assert (inputLen <= MaxPlainTextLength()); 

SecByteBlock pkcsBlock(modulusLen); 

pkcsBlock[0] = 0; 
pkcsBlock[1] = 1; // block type 1 

for (int i = 2; i < modulusLen - inputLen - 1; i++) 
pkcsBlock[i] = 0xff; 

pkcsBlock[i++] = 0; // separator 
memcpy(pkcsBlock+i, input, inputLen); 

bignum c; 
RawEncrypt(bignum(pkcsBlock, modulusLen), c); 
c.Encode(output, modulusLen); 
} 

unsigned int RSAPrivateKey::Decrypt(const byte *input, byte *output) 
{ 
bignum m; 
RawEncrypt(bignum(input, modulusLen), m); 

SecByteBlock pkcsBlock(modulusLen); 
m.Encode(pkcsBlock, modulusLen); 

// Require block type 2. 
if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 2)) 
return 0; 

for (int i = 2; i < modulusLen-1; i++) 
if (pkcsBlock[i] == 0) // separator 
break; 

if (++i >= modulusLen) 
return 0; 

unsigned int outputLen = modulusLen - i; 

if (outputLen > MaxPlainTextLength()) 
return 0; 

memcpy (output, pkcsBlock+i, outputLen); 
return outputLen; 
} 

void RSAPrivateKey::RawEncrypt(const bignum &amt;in, bignum &amt;out) const 
{ 
out = a_exp_b_mod_pq(in, dp, dq, p, q, u); 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -