SecureRandom impl that XORs the outputs of other impls (not yet used).

This can be used to combine e.g. the platform's SecureRandom
implementation with our own, so that a weakness in either source doesn't
harm security as long as the other source is strong.
This commit is contained in:
akwizgran
2014-03-21 15:04:55 +00:00
parent f3d2e52e11
commit bb38911dc8

View File

@@ -0,0 +1,67 @@
package org.briarproject.crypto;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
/**
* A {@link java.security.SecureRandom SecureRandom} implementation that
* combines the outputs of two or more other implementations using XOR.
*/
class CombinedSecureRandom extends SecureRandom {
private static final long serialVersionUID = -605269609862397104L;
private static final Provider PROVIDER = new CombinedProvider();
CombinedSecureRandom(SecureRandom... randoms) {
super(new CombinedSecureRandomSpi(randoms), PROVIDER);
}
private static class CombinedSecureRandomSpi extends SecureRandomSpi {
private static final long serialVersionUID = 483801767899979081L;
private final SecureRandom[] randoms;
private CombinedSecureRandomSpi(SecureRandom... randoms) {
if(randoms.length < 2) throw new IllegalArgumentException();
this.randoms = randoms;
}
@Override
protected byte[] engineGenerateSeed(int numBytes) {
byte[] combined = new byte[numBytes];
for(SecureRandom random : randoms) {
byte[] b = random.generateSeed(numBytes);
int length = Math.min(numBytes, b.length);
for(int i = 0; i < length; i++)
combined[i] = (byte) (combined[i] ^ b[i]);
}
return combined;
}
@Override
protected void engineNextBytes(byte[] b) {
byte[] temp = new byte[b.length];
for(SecureRandom random : randoms) {
random.nextBytes(temp);
for(int i = 0; i < b.length; i++)
b[i] = (byte) (b[i] ^ temp[i]);
}
}
@Override
protected void engineSetSeed(byte[] seed) {
for(SecureRandom random : randoms) random.setSeed(seed);
}
}
private static class CombinedProvider extends Provider {
private static final long serialVersionUID = -4678501890053703844L;
private CombinedProvider() {
super("Combined", 1.0, "");
}
}
}