Pgp: Not Enough Random Bytes Available. Please Do Some Other Work to Give the Os a Chance to Collect More Entropy

GPG error Not enough random bytes available. Please do some other work to give the OS a chance to collect more

You can move your mouse around, browse the internet, play a game, leave your computer on overnight. There are many many ways to generate random bytes. You don't need to babysit the gpg process.

EDIT: I should clarify: you don't need to pay attention or even type into the terminal that gpg is running in. (And it's a really bad idea to type into that terminal anyway.)

If you're on a remote server, and cannot otherwise generate work, you can try this: http://packages.debian.org/squeeze/stress. Use caution, though.

GPG hangs on entropy generation

Although rng-tools will work, this is not suggested since it doesn't provide real entropy. See the discussion here: https://bugs.launchpad.net/ubuntu/+source/gnupg/+bug/706011

For users that are frustrated by this, here are some things I found helpful on a server with no mouse/desktop.

1) Go through the process of creating the GPG key. If it hangs waiting for more entropy, go to the next step.

2) You can watch how much entropy your system has by opening a terminal and type (this will look at that file every second):

watch -n1 cat /proc/sys/kernel/random/entropy_avail

3) Open a third terminal to generate your entropy. You can try various things to try to boost that entropy. Here are some things that I noticed increased the entropy sufficiently to make gpg work. Note that this was somewhat random (no pun intended). Sometimes doing something would increase the entropy; but when I do it again, it does not:

Get a large file from the internet

wget http://us1.php.net/get/php-7.2.2.tar.bz2/from/this/mirror

Do something that prints a lot of stuff to the terminal:

ls -R /
sudo find /folder/with/lots/of/files/ -type f | xargs grep 'simple string that shows up in lots of files'

4) If what you are doing does not increase the entropy_avail, then try something else.

What is the entropy of XORed CSPRNG bytes with low entropy hash?

You are describing a one-time-pad. If the key stream: the output of the CSPRNG is fully random then the ciphertext will be indistinguishable from random as well.

Of course the output of CSPRNG is not fully random. However, if the CSPRNG is well seeded with enough entropy then you'd have the same security as a stream cipher, which mimics a one time pad.

So the output (mixed) will be as random as the CSPRNG, as long as the CSPRNG doesn't get into a previously encountered state. That should basically only happen if the entropy source fails.

Please rectify my entropy code

Here is a direct port of the C# code into VB.NET:

Public Shared Function ShannonEntropy(s As String) As Double
Dim map = New Dictionary(Of Char, Integer)()
For Each c As Char In s
If Not map.ContainsKey(c) Then
map.Add(c, 1)
Else
map(c) += 1
End If
Next

Dim result As Double = 0.0
Dim len As Integer = s.Length
For Each item As var In map
Dim frequency = CDbl(item.Value) / len
result -= frequency * (Math.Log(frequency) / Math.Log(2))
Next

Return result
End Function

If the C# code produces the results you were looking for, this code will give the same results.

Fail to gpg-decrypt BouncyCastlePGP-encrypted message

The problem with the encryptKeyBytes implementation, which is where the encrypted PGP message gets built, is that it writes the plain-text message octets as is, as opposed to as literal data, hence the protocol error during the decryption attempt.

A correct implementation looks like:

private byte[] encryptKeyBytes(String keyName, byte[] keyBytes, byte[] pgpKey)
throws GeneralSecurityException {
ByteArrayOutputStream encKeyBytes = new ByteArrayOutputStream(keyBytes.length);

try (Handle<SecureRandom> randomHandle = RngSupport.getRandom()) {
JcePGPDataEncryptorBuilder encryptorBuilder =
new JcePGPDataEncryptorBuilder(PGPEncryptedDataGenerator.AES_256);
encryptorBuilder.setWithIntegrityPacket(true);
encryptorBuilder.setSecureRandom(randomHandle.getObject());
encryptorBuilder.setProvider("BC");

PGPEncryptedDataGenerator encryptor = new PGPEncryptedDataGenerator(encryptorBuilder);
try {
JcePublicKeyKeyEncryptionMethodGenerator keyEncryptionMethodGenerator =
new JcePublicKeyKeyEncryptionMethodGenerator(resolvePgpPublicKey(pgpKey));
keyEncryptionMethodGenerator.setProvider("BC");
encryptor.addMethod(keyEncryptionMethodGenerator);

PGPLiteralDataGenerator dataGenerator = new PGPLiteralDataGenerator();
byte[] data = BytesSupport.encodeHex(keyBytes).getBytes(StandardCharsets.UTF_8);
try (
OutputStream ao = new ArmoredOutputStream(encKeyBytes);
OutputStream eo = encryptor.open(ao, keyBytes.length);
OutputStream go = dataGenerator.open(
eo, PGPLiteralData.UTF8, keyName, data.length, new Date())) {
go.write(data);
}
} catch (ServiceRequestException e) {
throw e;
} catch (Exception e) {
throw new GeneralSecurityException("Cannot perform PGP encryption on the content key", e);
}
}

return encKeyBytes.toByteArray();
}

Notice the use of PGPLiteralDataGenerator, which is the abstraction that provides the output stream on which the message bytes get written to.

using ssl in wcf service

Yes, if that's what you want to do:

  • you'll have SSL-enabled HTTPS transport
  • you're using the wsHttp binding
  • your users will be authenticated against the Windows domain (Active Directory)

This requires that your client and server are in the same common Windows domain, or at least in two Windows domains that are in a mutual trust relationship with one another (so that the service can authenticate the calling user against Active Directory).

This will not support anonymous callers, or callers from outside your Windows domain.

The question is: if it's really within your Windows domain and thus behind your corporate firewall, why are you using wsHttpBinding? NetTcpBinding would be much faster and more efficient in this scenario....

Marc



Related Topics



Leave a reply



Submit