Mercurial > 510Connectbot
view src/ch/ethz/ssh2/crypto/SecureRandomFix.java @ 346:d6ab7b606a50
compensate for SecureRandom bug on older devices
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 31 Jul 2014 18:51:21 -0700 |
parents | 663637117cf8 |
children | bb7d8a7babbe |
line wrap: on
line source
// // Copyright (C) 2014 by 510 Software Group // licensed under the GPLv3 or later package ch.ethz.ssh2.crypto; import android.os.Build; import android.os.Process; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.SecureRandom; class SecureRandomFix extends SecureRandom { // http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18; private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL = getBuildFingerprintAndDeviceSerial(); private static byte[] generateReasonableSeed() { try { ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream(); DataOutputStream seedBufferOut = new DataOutputStream(seedBuffer); seedBufferOut.writeLong(System.currentTimeMillis()); seedBufferOut.writeLong(System.nanoTime()); seedBufferOut.writeInt(Process.myPid()); seedBufferOut.writeInt(Process.myUid()); seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL); seedBufferOut.close(); return seedBuffer.toByteArray(); } catch (IOException e) { throw new SecurityException("Failed to generate seed", e); } } /** * Gets the hardware serial number of this device. * * @return serial number or {@code null} if not available. */ private static String getDeviceSerialNumber() { // We're using the Reflection API because Build.SERIAL is only available // since API Level 9 (Gingerbread, Android 2.3). try { return (String) Build.class.getField("SERIAL").get(null); } catch (Exception ignored) { return null; } } private static byte[] getBuildFingerprintAndDeviceSerial() { StringBuilder result = new StringBuilder(); String fingerprint = Build.FINGERPRINT; if (fingerprint != null) { result.append(fingerprint); } String serial = getDeviceSerialNumber(); if (serial != null) { result.append(serial); } try { return result.toString().getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("UTF-8 encoding not supported"); } } public SecureRandomFix() { super(); if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) { // No need to apply the fix return; } setSeed(generateReasonableSeed()); } }