这篇文章专门分析Android中的一个服务:EntropyMixer,源代码位于:
framework/base/service/core/java.com.android.server.EntropyMixer.java,该类继承自Binder,总共也就二百多行,
Entropy翻译做熵,是Linux系统中描述系统有序性的一个标识,该值越大表示系统有序性越差,在Android中EntropyMixer 就是是以前的EntropyService,生成随机数的一个东西。随机数一般与密码,加密等相关。
计算机本身是个可以预测的系统,用计算机生成的随机数的随机性就显得不是那么高,怎么办呢?注意到系统中充满了各种噪音(不是你听到的声音),有些是有序的噪音,但是有些是不可预测的随机噪音,如
用户点击鼠标的时间间隔、用户敲击键盘的时间间隔、硬件设备发生中断的时间等,都是无法预测的事件,Linux系统的RNG(随机数生成器)所生成的随机数正是利用系统中这些噪音来产生的高质量的随机数序列,
内核维护了一个熵池(EntropyPool)收集来自设备驱动程序和其他来源的环境噪音:
/**
* Mixes in the output from HW RNG (if present) into the Linux RNG.
*/
private void addHwRandomEntropy() {
try {
//我理解hw就是hardware
RandomBlock.fromFile(hwRandomDevice).toFile(randomDevice, false);
Slog.i(TAG, "Added HW RNG output to entropy pool");
} catch (FileNotFoundException ignored) {
// HW RNG not present/exposed -- ignore
} catch (IOException e) {
Slog.w(TAG, "Failed to add HW RNG output to entropy pool", e);
}
}
该方法将驱动设备的随机时间写入到randomDevice供生成随机数使用,在哪里调用呢?
1.构造函数:
/** Test only interface, not for public use */
public EntropyMixer(
Context context,
String entropyFile,
String randomDevice,
String hwRandomDevice) {
if (randomDevice == null) { throw new NullPointerException("randomDevice"); }
if (hwRandomDevice == null) { throw new NullPointerException("hwRandomDevice"); }
if (entropyFile == null) { throw new NullPointerException("entropyFile"); }
this.randomDevice = randomDevice;
this.hwRandomDevice = hwRandomDevice;
this.entropyFile = entropyFile;
loadInitialEntropy();
addDeviceSpecificEntropy();
addHwRandomEntropy();
writeEntropy();
scheduleEntropyWriter();
IntentFilter broadcastFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
broadcastFilter.addAction(Intent.ACTION_POWER_CONNECTED);
broadcastFilter.addAction(Intent.ACTION_REBOOT);
context.registerReceiver(mBroadcastReceiver, broadcastFilter);
}
2.Handler中,每隔3h调用一次:
private void scheduleEntropyWriter() {
mHandler.removeMessages(ENTROPY_WHAT);
mHandler.sendEmptyMessageDelayed(ENTROPY_WHAT, ENTROPY_WRITE_PERIOD);
}
/**
* Handler that periodically updates the entropy on disk.
*/
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what != ENTROPY_WHAT) {
Slog.e(TAG, "Will not process invalid message");
return;
}
addHwRandomEntropy();
writeEntropy();
scheduleEntropyWriter();
}
};
最终调用writeEntropy方法:
private void writeEntropy() {
try {
Slog.i(TAG, "Writing entropy...");
RandomBlock.fromFile(randomDevice).toFile(entropyFile, true);
} catch (IOException e) {
Slog.w(TAG, "Unable to write entropy", e);
}
}
最终写入到entropyFile,即:
public EntropyMixer(Context context) {
this(context, getSystemDir() + "/entropy.dat", "/dev/urandom", "/dev/hw_random");
}
/entropy.dat
此外在构造方法中还可以看到注册了一个广播接收器:
IntentFilter broadcastFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
broadcastFilter.addAction(Intent.ACTION_POWER_CONNECTED);
broadcastFilter.addAction(Intent.ACTION_REBOOT);
context.registerReceiver(mBroadcastReceiver, broadcastFilter);
在关机、接通电源、重启都会触发:
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
writeEntropy();
}
};
总结:通过上面的分析,EntropyMixer就是一个不断收集系统中随机时间并记录,为系统生成高质量的随机数服务,同时也可以服务于一些加密的任务。
基于Android5.1源码分析
如有不对的地方,请指教,谢谢
参考:
http://blog.csdn.net/wangzengke/article/details/9138413 感谢