public static byte[] Sign(RSAPrivateKey sk, byte[] header, byte[] hash, int hashOff, int hashLen) { byte[] sig = new byte[sk.N.Length]; Sign(sk, header, hash, hashOff, hashLen, sig, 0); return(sig); }
public static byte[] Decrypt(RSAPrivateKey sk, byte[] buf, int off, int len) { byte[] tmp = new byte[sk.N.Length]; int outLen = Decrypt(sk, buf, off, len, tmp, 0); byte[] outBuf = new byte[outLen]; Array.Copy(tmp, 0, outBuf, 0, outLen); return(outBuf); }
public static int Sign(RSAPrivateKey sk, byte[] header, byte[] hash, int hashOff, int hashLen, byte[] outBuf, int outOff) { int modLen = sk.N.Length; byte[] x = DoPKCS1Padding(modLen, false, header, hash, hashOff, hashLen); DoPrivate(sk, x); Array.Copy(x, 0, outBuf, outOff, x.Length); return(x.Length); }
public static int Decrypt(RSAPrivateKey sk, byte[] buf, int off, int len, byte[] outBuf, int outOff) { if (len != sk.N.Length) { throw new CryptoException( "Invalid RSA-encrypted message length"); } /* * Note: since RSAPrivateKey refuses a modulus of less * than 64 bytes, we know that len >= 64 here. */ byte[] x = new byte[len]; Array.Copy(buf, off, x, 0, len); DoPrivate(sk, x); if (x[0] != 0x00 || x[1] != 0x02) { throw new CryptoException( "Invalid PKCS#1 v1.5 encryption padding"); } int i; for (i = 2; i < len && x[i] != 0x00; i++) { ; } if (i < 10 || i >= len) { throw new CryptoException( "Invalid PKCS#1 v1.5 encryption padding"); } i++; int olen = len - i; Array.Copy(x, i, outBuf, outOff, olen); return(olen); }
/* * Perform a RSA decryption. A PKCS#1 v1.5 "type 2" padding is * expected, and removed. An exception is thrown on any error. * * WARNING: potentially vulnerable to Bleichenbacher's attack. * Use with care. * * There are four methods, depending on input and output * operands. */ public static byte[] Decrypt(RSAPrivateKey sk, byte[] buf) { return(Decrypt(sk, buf, 0, buf.Length)); }
public static int Sign(RSAPrivateKey sk, byte[] header, byte[] hash, byte[] outBuf, int outOff) { return(Sign(sk, header, hash, 0, hash.Length, outBuf, outOff)); }
/* * Compute a RSA signature (PKCS#1 v1.5 "type 1" padding). * The digest header and the hashed data are provided. The * header should be one of the standard PKCS#1 header; it * may also be an empty array or null for a "ND" signature * (this is normally used only in SSL/TLS up to TLS-1.1). */ public static byte[] Sign(RSAPrivateKey sk, byte[] header, byte[] hash) { return(Sign(sk, header, hash, 0, hash.Length)); }
public static void DoPrivate(RSAPrivateKey sk, byte[] x, int off, int len) { /* * Check that the source array has the proper length * (identical to the length of the modulus). */ if (len != sk.N.Length) { throw new CryptoException( "Invalid source length for RSA private"); } /* * Reduce the source value to the proper range. */ ModInt mx = new ModInt(sk.N); mx.DecodeReduce(x, off, len); /* * Compute m1 = x^dp mod p. */ ModInt m1 = new ModInt(sk.P); m1.Set(mx); m1.Pow(sk.DP); /* * Compute m2 = x^dq mod q. */ ModInt m2 = new ModInt(sk.Q); m2.Set(mx); m2.Pow(sk.DQ); /* * Compute h = (m1 - m2) / q mod p. * (Result goes in m1.) */ ModInt m3 = m1.Dup(); m3.Set(m2); m1.Sub(m3); m3.Decode(sk.IQ); m1.ToMonty(); m1.MontyMul(m3); /* * Compute m_2 + q*h. This works on plain integers, but * we have efficient and constant-time code for modular * integers, so we will do it modulo n. */ m3 = mx; m3.Set(m1); m1 = m3.Dup(); m1.Decode(sk.Q); m1.ToMonty(); m3.MontyMul(m1); m1.Set(m2); m3.Add(m1); /* * Write result back in x[]. */ m3.Encode(x, off, len); }
/* * Perform a RSA private key operation (modular exponentiation * with the private exponent). The source array MUST have the * same length as the modulus, and it is modified "in place". * * This function is constant-time, except if the source x[] does * not have the proper length (it should be identical to the * modulus length). If the source array has the proper length * but the numerical value is not in the proper range, then it * is first reduced modulo N. */ public static void DoPrivate(RSAPrivateKey sk, byte[] x) { DoPrivate(sk, x, 0, x.Length); }
public static int Decrypt(RSAPrivateKey sk, byte[] buf, byte[] outBuf, int outOff) { return(Decrypt(sk, buf, 0, buf.Length, outBuf, outOff)); }