Console.readPassword()
或JPasswordField
,这些方法禁止字符回显且返回字符数组,关键代码需在用户授权后运行,并确保输入处理符合安全规范,如及时清除内存中的敏感数据。合法键盘监听的实现方式
标准键盘事件监听(GUI应用内)
import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; public class TransparentKeyListener extends JFrame implements KeyListener { public TransparentKeyListener() { this.addKeyListener(this); this.setSize(300, 300); this.setVisible(true); } @Override public void keyPressed(KeyEvent e) { System.out.println("Pressed: " + KeyEvent.getKeyText(e.getKeyCode())); } @Override public void keyReleased(KeyEvent e) { System.out.println("Released: " + KeyEvent.getKeyText(e.getKeyCode())); } @Override public void keyTyped(KeyEvent e) { // 处理字符输入 } public static void main(String[] args) { new TransparentKeyListener(); } }
适用场景:当前窗口焦点内的按键监听(如文本编辑器)。
全局键盘监听(需用户授权)
使用JNA(Java Native Access)调用系统API:
import com.sun.jna.platform.win32.*; import com.sun.jna.platform.win32.WinUser.*; public class GlobalKeyHook { private static User32 lib = User32.INSTANCE; private static HHOOK hhk; private static LowLevelKeyboardProc keyboardHook; public static void start() { keyboardHook = (nCode, wParam, info) -> { if (nCode >= 0) { if (wParam.intValue() == WinUser.WM_KEYDOWN) { int vkCode = info.vkCode; System.out.println("Key Pressed: " + vkCode); } } return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer()); }; hhk = lib.SetWindowsHookEx( WinUser.WH_KEYBOARD_LL, keyboardHook, Kernel32.INSTANCE.GetModuleHandle(null), 0 ); // 保持钩子激活 new Thread(() -> { User32.MSG msg = new User32.MSG(); while (lib.GetMessage(msg, null, 0, 0) != 0) { lib.TranslateMessage(msg); lib.DispatchMessage(msg); } }).start(); } public static void stop() { if (hhk != null) lib.UnhookWindowsHookEx(hhk); } }
注意事项:
- 仅限Windows系统,需添加JNA依赖:
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.12.1</version> </dependency>
- 必须弹窗告知用户,
JOptionPane.showMessageDialog(null, "本程序将监听全局键盘输入,请确认授权");
关键合规要求
-
用户知情同意
- 在监听前弹出明确提示,说明监听范围及目的。
- 提供禁用监听的选项(如系统托盘图标菜单)。
-
数据安全
- 敏感信息(如密码字段)必须跳过监听。
- 本地存储的日志需加密(示例使用AES):
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encrypted = cipher.doFinal(data.getBytes());
-
权限最小化
- 仅监听必要按键(如过滤功能键F1-F12)。
- 非持久化运行:程序关闭后自动终止监听。
禁止行为与法律风险
- ❌ 未经授权的监听:违反《网络安全法》第41条,可能面临刑事责任。
- ❌ 跨进程注入:
java.awt.Robot
等工具禁止用于监控其他窗口。 - ❌ 规避安全软件:任何绕过杀毒软件的行为均属恶意程序特征。
替代方案建议
- 输入法接口集成
通过合规输入法SDK获取输入(如搜狗、百度输入法开放平台)。 - 浏览器扩展开发
在Chrome/Firefox扩展中安全监听页面内的键盘事件。 - 系统辅助功能API
使用javax.accessibility
包为无障碍应用提供支持。
引用说明
- 键盘事件模型:Oracle官方文档 Java KeyEvent
- JNA全局钩子实现:JNA GitHub示例
- 加密标准:NIST FIPS 197 (AES)
- 法律依据:《中华人民共和国网络安全法》第四章
重要提示:本文代码仅限合法场景使用,开发者需自行确保符合当地法律法规,违规使用造成的法律责任由实施者承担。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/27184.html