I wrote my own implementation of the RSA digital signature. I use SHA-512 hashing. I sign the picture in png format. At the output, I get a signature of 512 bytes, is this normal or a bug?
It turns out that it is due to the fact that our hash has a length of 64 bytes, the maximum number generated by me can have a weight of 8 bytes, it turns out 1 byte of the file = 8 bytes of digital signature. The hashToInt function represents an array of bytes as an array of ints (add 256 to negative bytes). Made to adequately perform the ModPow operation
Random random = new Random();
byte[] byteArray = new byte[8];
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
byte[] array = Files.readAllBytes(Path.of("C:\\Users\\User\\IdeaProjects\\CryptoLab1\\src\\crypto\\dino.png"));
byte[] hash = sha512.digest(array);
var hashInt = hashToIntArray(hash);
FileOutputStream out = new FileOutputStream("C:\\Users\\User\\IdeaProjects\\CryptoLab1\\src\\crypto\\DigitalSignatureRSA.png");
BigInteger P = BigInteger.probablePrime(32, random);
BigInteger Q = BigInteger.probablePrime(32, random);
BigInteger N = P.multiply(Q);
BigInteger f = (P.subtract(BigInteger.ONE)).multiply(Q.subtract(BigInteger.ONE));
BigInteger d;
BigInteger c;
BigInteger signature;
BigInteger checkSignature;
do {
d = new BigInteger(32, random);
} while (!(d.gcd(f).equals(BigInteger.ONE)) && d.compareTo(f) < 0);
c = d.modInverse(f);
List<BigInteger> digitalSignature = new ArrayList<>();
List<BigInteger> deDigitalSignature = new ArrayList<>();
List<byte[]> byteList = new ArrayList<>();
//create a digital signature
for (int i = 0; i < hash.length; i++) {
BigInteger y = BigInteger.valueOf(hashInt[i]);
signature = cryptoLab1.ModPow(y, c, N);
digitalSignature.add(signature);
byteArray = toHH(signature); //toHH - representation of a number in 8 byte format
byteList.add(byteArray);
out.write(byteList.get(i));
}
// numeric signature verification
var fileData = Files.readAllBytes(Path.of("C:\\Users\\User\\IdeaProjects\\CryptoLab1\\src\\crypto\\dino.png"));
var hashFileData = hashToIntArray(sha512.digest(fileData));
for (int i = 0; i < hash.length; i++) {
checkSignature = cryptoLab1.ModPow(digitalSignature.get(i), d, N);
deDigitalSignature.add(checkSignature);
}
for(int i = 0; i < hash.length; i++) {
if(BigInteger.valueOf(hashFileData[i]).equals(deDigitalSignature.get(i))) {
return true;
}
}
return false;
}