Comparte el portapapeles entre la PC (Windows) y el celular (Android). Lo que se envía va cifrado de punta a punta y, si los dispositivos están en la misma red, viaja directo entre ellos sin pasar por ningún servidor.
- Windows: vive en la bandeja del sistema. Ctrl+Shift+C envía lo que hay en el portapapeles y lo que llega se pega directo con Ctrl+V.
- Android: se envía desde Compartir → Clipboard o con el botón Enviar a PC de los ajustes rápidos. Lo que llega aparece como notificación con un botón Copiar.
| Proyecto | Qué tiene |
|---|---|
common/ |
Núcleo compartido: cifrado, pairing, sincronización y transporte LAN |
client/ |
App .NET MAUI + Blazor Hybrid para Windows y Android |
server/ |
Futuro relay para cuando los dispositivos no están en la misma red (todavía es la plantilla) |
tests/ |
Tests de common con xUnit |
-
.NET SDK 10
-
Workload de MAUI:
dotnet workload install maui -
Para Android, el Android SDK y un JDK. El propio proyecto puede instalarlos:
dotnet build client/client.csproj -t:InstallAndroidDependencies -f net10.0-android -p:AndroidSdkDirectory=C:\Android\sdk -p:JavaSdkDirectory=C:\Android\jdk -p:AcceptAndroidSDKLicenses=TrueDespués conviene definir
ANDROID_HOME=C:\Android\sdkyJAVA_HOME=C:\Android\jdkpara no tener que pasar las rutas en cada build.
dotnet test tests/tests.csproj
Algunos tests usan la red real (multicast y TCP en la misma máquina).
dotnet build client/client.csproj -f net10.0-windows10.0.19041.0
El ejecutable queda en client/bin/Debug/net10.0-windows10.0.19041.0/win-x64/client.exe. La primera vez Windows puede preguntar si deja pasar la app por el firewall: hay que permitirla en redes privadas o el celular no la encuentra.
Para instalarlo directo en un celular conectado por USB, con la depuración USB activada:
dotnet build client/client.csproj -t:Run -f net10.0-android
Para generar un APK e instalarlo a mano:
dotnet publish client/client.csproj -f net10.0-android -c Release -p:AndroidPackageFormat=apk
Se instala client/bin/Release/net10.0-android/publish/com.lostdou.clipboard-Signed.apk. Sin un keystore propio, el APK queda firmado con la clave de debug del SDK. Para instalar a mano alcanza, pero para publicarlo hace falta una clave propia.
- Descubrimiento: cada dispositivo se anuncia por multicast UDP (
239.255.77.12:47123) y, por las dudas, también por broadcast. El anuncio lleva elGroupIddel grupo y el puerto TCP donde escucha. Al ver un dispositivo nuevo se le contesta enseguida, así que se encuentran en menos de un segundo. - Envío: cada clip viaja por una conexión TCP corta, en un sobre cifrado con AES-256-GCM. El sobre está atado al
GroupId, así que no sirve para otro grupo. - Recepción: se descartan los clips propios, los repetidos y los que tienen más de 2 minutos. Ese límite evita que alguien en la red capture un sobre y lo reenvíe más tarde.
El pairing no pasa por la red. El secreto viaja de un dispositivo al otro por el QR, o tipeado si son dos PCs.
-
El primer dispositivo genera un secreto aleatorio de 16 bytes (128 bits).
-
El secreto se muestra como QR y como un código de 28 caracteres:
XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX.- El código usa base32 de Crockford: no tiene I, L, O ni U, acepta minúsculas y toma la O como 0 y la I/L como 1.
- El último byte es un CRC-8. Cualquier error de tipeo en un carácter se detecta siempre, en vez de dar un código válido de un grupo que no existe.
-
El otro dispositivo escanea o tipea el código y llega al mismo secreto.
-
De ese secreto, cada uno deriva por su cuenta con HKDF dos valores independientes:
- la clave de cifrado, que nunca sale del dispositivo;
- el
GroupId, que es público: se anuncia en la red y es lo único que vería el relay.
Como el secreto es aleatorio y de 128 bits, conocer el
GroupIdno permite adivinarlo. -
El código se guarda en
SecureStorage(Keystore en Android) para no volver a emparejar. Cualquier dispositivo del grupo puede mostrarlo de nuevo para sumar otro.
Quien vea el código puede unirse al grupo, así que se muestra solo cuando se pide. Para sacar a un dispositivo hay que crear un grupo nuevo y volver a emparejar el resto.
- Server / relay para sincronizar cuando los dispositivos no están en la misma red. Antes hay que definir:
- cómo se reparten los envíos entre LAN y relay con 3 o más dispositivos (hoy se corta en el primer transporte que entrega);
- qué pasa con los clips que esperan en el relay más de los 2 minutos de la ventana de recepción.
- Una sola instancia en Windows: abrir la app dos veces hoy deja dos íconos en la bandeja.
- Android: bugs visuales y correcciones pendientes.
- Ctrl+Shift+C choca con "copiar" en Windows Terminal y en la terminal de VS Code; hacer configurable el atajo.
- Arranque automático con Windows.
- Imágenes: hoy solo se sincroniza texto.