RSA private key and public key - math

Little stuck on how to approach this question:
Xavier and Yvonne are in love. They both set up their own RSA keys:
Xavier’s public key is (eX , nX ) = (887, 15833), and Yvonne’s public key
is (eY , nY ) = (977, 13019). For each of the following, do not factor nX nor
nY , show the set up of the calculations and the results. You should use a
computer to perform the calculations.
(a) Yvonne wants to send Xavier a private message of love, which is
M = 3141. What is the ciphertext that Yvonne needs to send to Xavier?
(b) In return, Yvonne received three mysterious messages: C1 = 10889,
C2 = 2622, C3 = 4061. All three senders claim to be Xavier, and all
claim to have sent the message Ci ≡ MdX (mod nX) where M = 3141 and dX
is Xavier’s private key. However, only Xavier himself knows the actual
value of dX , and the other two are imposters trying to steal Yvonne away
from him. Help Yvonne determine which message is actually from Xavier,
and explain why your method works.
Any tips would be great thanks!

a) In order to send an RSA-encrypted message such that only the private key holder can decrypt it, it must be encrypted using the recipient's public key. In this case, the recipient is Xavier, so the message is encrypted using his public key: (eX, nX) = (887, 15833):
Message: M = 3141
Ciphertext: C = MeX mod nX
C = 3141887 mod 15833
C = 2054
b) This is essentially a signature verification of a message signed using Xavier's private key, which requires the use of the signer's public key. It is necessary to find which of the three messages, when decrypted using Xavier's public key results in the message that was sent (3141):
Ciphertext 1: C1 = 10889
Message 1: M1 = C1eX mod nX
M1 = 10889887 mod 15833
M1 = 6555 (mismatch)
Ciphertext 2: C2 = 2622
Message 2: M2 = C2eX mod nX
M2 = 2622887 mod 15833
M2 = 1466 (mismatch)
Ciphertext 3: C3 = 2622
Message 3: M3 = C3eX mod nX
M3 = 4061887 mod 15833
M3 = 3141 (match!)
Only C3 matches the message when decrypted using Xavier's public key, and so is the only authentic message.
Note: I used WolframAlpha to perform the modular exponentiation above, but it's easy enough (though rather more time-consuming) to do manually using repeated multiplication then reduction modulo n.

Related

How to perform a Franklin Reiter Related Message Attack on RSA?

By definition, the Franklin Reiter related message attack works in a scenario where two messages differ only by a fixed known difference. Suppose I have two messages encrypted by RSA with the same public key (N, e), where:
M1 = "Hello " + name1 + message
M2 = "Hello " + name2 + message
How can I perform the Franklin-Reiter related message attack on them?
I am aware that we need (N, e, C1, C2, f) for a Franklin Reiter related message attack where f = ax + b, but what is f in this case?

Is there anyway to tell if a RSA public key pair is correct?

I got a quiz question asking which of the following pair(n,e) is a correct RSA public key?
n = 437 and e = 7
n = 437 and e = 11
Hint 437 = 19*23
Is there anyway to tell is a RSA public key correct? Or I've must missed some important content
Short Answer:
The 2nd one is incorrect. Because gcd(e, lambda(n)) must be 1, but it is not in 2nd case.
Long answer:
Go through RSA key generation:
n=437 and 437=19*23, so p, q are 19, 23.
lambda(437)=(p-1)*(q-1)=18*22
Now we need to select e in a way 1<e<lambda(n) and gcd(e, lambda(n))=1 meaning e and lambda(n) are coprime.
But in 2nd case, gcd(11, lambda(437))=11, so they are not coprime and we cannot use e=11.

decrypting RSA using c^d mod n

I'm trying to get a message out of an RSA code, but cant seem to understand
how.
The formula i'm trying to use to find the message is: c^d mod n.
In the text file i received (which is the RSA code), i have 3 parameters:
The c parameter:
c=62094327354293714871337806608043143339672711375275261525243238242322194473023610842261452370807533140129255594935713596899492336925573500404508972313463258470764117200138784924348362580128423518572743446058119722861164424364186271770831857887818550880280385895469933434901508250872871673722739401583613920865
the N parameter:
N=102518413348128616948064302091615267327586561544914497024946023154172320251650248158262401038211060025769143033483116931749752882566368072181993447378932810603880706573407783516535716219705301632360773290434984792276962906314924125193872533986871367036809927042370179209563059349511562287725586162360516841779
and the d parameter:
d=90575112832191634931822012293951618304193311969935139031973154594700485026947413962490036848108653090804963912366135718482295366073482828257042351498160831683665400283336482471506944874247073018050011183570224881323949477869741822928092177900190031155493051065073868895195339892585741809998466654281718606993
Now the problem is that the numbers are WAY too long (308 digits long, and the N parameter is 309 digits long). I couldn't find any calculator that can calculate c^d so far.
any help?
You can do that with java using math.BigInteger
BigInteger c = new BigInteger("62094327354293714871337806608043143339672711375275261525243238242322194473023610842261452370807533140129255594935713596899492336925573500404508972313463258470764117200138784924348362580128423518572743446058119722861164424364186271770831857887818550880280385895469933434901508250872871673722739401583613920865");
BigInteger N = new BigInteger("102518413348128616948064302091615267327586561544914497024946023154172320251650248158262401038211060025769143033483116931749752882566368072181993447378932810603880706573407783516535716219705301632360773290434984792276962906314924125193872533986871367036809927042370179209563059349511562287725586162360516841779");
BigInteger d = new BigInteger("90575112832191634931822012293951618304193311969935139031973154594700485026947413962490036848108653090804963912366135718482295366073482828257042351498160831683665400283336482471506944874247073018050011183570224881323949477869741822928092177900190031155493051065073868895195339892585741809998466654281718606993");
BigInteger m = new BigInteger("1");
m = c.modPow(d, N);
System.out.println(m);
And the result would be
12095051301478169748702315942951183566712581822646196016924926165965065297342257

Cretate multiple shared secrets in a (selfmade) public/privavte key infrastructure

I just try to understand cryptography, please be concern. Its not meant to be secure or professional. I create 3 numbers for each party. a public key, a secret key and a modulus. The first party (A) creates his keys
let pri = 133
let mod = 256
let pub = mod - pri
and shares "mod" and "pub" to other partys (B, C). When B want to encrypt a string he takes A's public key and modulus and do
// B encrypts
let enc = ( input + pubA ) % modA
A on his side is doing
// B decrypts
let dec = ( enc + priA) % modA
to decrypt it. My problem is, i can create multiple keypairs but only 1 associated public key to each secret key because i have to share the modulus of each pair for en/decryption.
Is it possible (in this situation) to create multiple publics numbers for a single private number? And if so, how can i do it?
Thank you (and sorry if this is a poor question)
EDIT Even if its not "good" to create your own cipher i want to do so..
I recognized that i missed the secret exponent d so that phi divides (e * expo)-1.
/* Pseude code */
p = q = primes()
n = p * q
phi = (p-1) * (q-1)
e = 3
d = ? // <-- have to find my own secret exponent!
if( gcd(e, p-1) != gcd(e, q-1) ) exit(0)
expo = 0
for(expo < 100000)
if( (e * expo)-1 == phi ) ) d = expo
And therefore i could have
public(n,e)
private(n,d)
so i can share (n,e). Is that correct?

R RSA signature raw to character and back

SO I am using the R PKI package, thanks to Simon Urbanek, and am trying to understand the application of signing a message.
So I can figure out how to sign something.
require(PKI)
# generate 2048-bit RSA key
key <- PKI.genRSAkey(bits = 2048L)
# extract private and public parts as PEM
priv.pem <- PKI.save.key(key)
pub.pem <- PKI.save.key(key, private=FALSE)
# load back the public key separately
pub.k <- PKI.load.key(pub.pem)
# encrypt with the public key
x <- PKI.encrypt(charToRaw("Hello, world!"), pub.k)
# decrypt with private key
rawToChar(PKI.decrypt(x, key))
# So straight from the Package examples I have the public and private keys.
# Additionally, with the same I can sign a message
x <- charToRaw("My message to sign")
sig <- PKI.sign(x, key)
PKI.verify(x, sig, key)
# Now a slight change from the exapmles I will verify that the public key can verify
PKI.verify(x, sig, pub.k)
pub.pem can be written to a file as
PuK<-paste(pub.pem, collapse="")
and can later be reconstructed via
pub.pem<-substring(PuK,
c(1, 27, 91, 155, 219, 283, 347, 411, 419),
c(26, 90,154,218,282,346,410,418,442))
pub.k <- PKI.load.key(pub.pem)
and then verified again as
PKI.verify(x, sig, pub.k)
However, sig is raw
str(sig)
and when it is written to a file you get
sig<-paste(sig, collapse=" " )
but you can no longer verify the signature as it is now a string and not raw and charToRaw does not recreate the original signature. I can get part of the way there but not to get a correctly formatted raw vector to verify the signature
sigraw<-rawToChar(sig2, multiple = TRUE)
str(sapply(sigraw, FUN=charToRaw))
So is there a way I can write the signature to a file and then back again to verify a signature?
Not sure this is the most direct answer to the question but it does allow for a text sting that can be written to file and then reformatted.
library("BMS")
library("PKI")
library("pack")
# generate 2048-bit RSA key
key <- PKI.genRSAkey(bits = 2048L)
# extract private and public parts as PEM
priv.pem <- PKI.save.key(key)
pub.pem <- PKI.save.key(key, private=FALSE)
# load back the public key separately
pub.k <- PKI.load.key(pub.pem)
x <- charToRaw("My message to sign")
sig <- PKI.sign(x, key)
PKI.verify(x, sig, key)
bits<-rawToBits(sig)
### This part can be skipped, long way to make character vector & back ###
pbitsb<-paste(bits)
back<-sapply(pbitsb, FUN=as.raw)
back==bits
sigbits<-packBits(bits, type="raw")
sigback<-packBits(back, type="raw")
sig==sigbits&sigbits==sigback
PKI.verify(x,sigback,key)
#Can make this more compressed character vector
hexsig<-bin2hex(as.numeric(bits))
#This is the value to be shared in a text file as proof of signature
#The remaineder needs to be executed by the recipient
binsig<-hex2bin(hexsig)
backbin<-sapply(binsig, FUN=as.raw)
sigbin<-packBits(backbin, type="raw")
PKI.verify(x,sigbin,key)
sig==sigbits&sigbits==sigback&sigback==sigbin

Resources