From 6de6001cf26d7afc205c7e0a1d7b683ab5c1cc7f Mon Sep 17 00:00:00 2001 From: david_bai Date: Fri, 27 Jun 2025 23:36:55 +0800 Subject: [PATCH] replace SecureShare/ with securityshare.xyz/privydrop.app --- README.md | 3 +- README.zh-CN.md | 2 +- backend/docker/Nginx/default | 2 +- .../docker/TURN/turnserver_development.conf | 4 +- frontend/app/[lang]/about/page.tsx | 6 +- frontend/app/[lang]/blog/[slug]/metadata.ts | 8 +- frontend/app/[lang]/blog/metadata.ts | 10 +- frontend/app/[lang]/blog/tag/[tag]/page.tsx | 10 +- frontend/app/[lang]/faq/page.tsx | 6 +- frontend/app/[lang]/help/HelpContent.tsx | 4 +- frontend/app/[lang]/help/page.tsx | 6 +- frontend/app/[lang]/page.tsx | 6 +- frontend/app/[lang]/privacy/page.tsx | 6 +- frontend/app/[lang]/terms/page.tsx | 6 +- frontend/app/sitemap.ts | 2 +- frontend/components/web/Footer.tsx | 2 +- frontend/components/web/Header.tsx | 4 +- frontend/components/web/HowItWorks.tsx | 2 +- frontend/components/web/SystemDiagram.tsx | 2 +- frontend/constants/messages/de.ts | 80 +++--- frontend/constants/messages/en.ts | 80 +++--- frontend/constants/messages/es.ts | 247 +++++++++++------- frontend/constants/messages/fr.ts | 80 +++--- frontend/constants/messages/ja.ts | 80 +++--- frontend/constants/messages/ko.ts | 80 +++--- frontend/constants/messages/zh.ts | 80 +++--- .../content/blog/webRTC-file-transfer-en.mdx | 90 ++++--- .../content/blog/webRTC-file-transfer-zh.mdx | 129 +++++---- frontend/public/robots.txt | 2 +- 29 files changed, 566 insertions(+), 473 deletions(-) diff --git a/README.md b/README.md index a055cc6..4ee7a18 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ PrivyDrop(formerly SecureShare) is an open-source, peer-to-peer (P2P) file and t We believe everyone should have control over their own data. PrivyDrop was created to fulfill this vision: a simple, fast, and private sharing solution. -[**Try it Live »**](https://www.securityshare.xyz/) | [**GitHub Repository »**](https://github.com/david-bai00/PrivyDrop) +[**Try it Live »**](https://www.privydrop.app/) | [**GitHub Repository »**](https://github.com/david-bai00/PrivyDrop) --- @@ -87,7 +87,6 @@ We warmly welcome contributions of all forms! Whether it's reporting a bug, sugg We have a [**Code of Conduct**](./.github/CODE_OF_CONDUCT.md) that all contributors are expected to follow. Please be sure to review it before participating. - ## 📄 License This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details. diff --git a/README.zh-CN.md b/README.zh-CN.md index bce2f8c..866ec54 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -6,7 +6,7 @@ PrivyDrop (原 SecureShare) 是一个基于 WebRTC 的开源点对点(P2P) 我们相信,每个人都应掌控自己的数据。PrivyDrop 的诞生就是为了实现这一愿景:一个简单、快速、私密的分享解决方案。 -[**在线体验 (原 SecureShare) »**](https://www.securityshare.xyz/) | [**GitHub 仓库 »**](https://github.com/david-bai00/PrivyDrop) +[**在线体验 »**](https://www.privydrop.app/) | [**GitHub 仓库 »**](https://github.com/david-bai00/PrivyDrop) --- diff --git a/backend/docker/Nginx/default b/backend/docker/Nginx/default index 1c46cde..fca895e 100644 --- a/backend/docker/Nginx/default +++ b/backend/docker/Nginx/default @@ -85,7 +85,7 @@ server { proxy_set_header X-Forwarded-Proto $scheme; # Modify CORS configuration, only set one Origin - add_header Access-Control-Allow-Origin "https://www.securityshare.xyz" always; + add_header Access-Control-Allow-Origin "https://www.privydrop.app" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" always; add_header Access-Control-Allow-Credentials "true" always; diff --git a/backend/docker/TURN/turnserver_development.conf b/backend/docker/TURN/turnserver_development.conf index 2cee314..932aedd 100644 --- a/backend/docker/TURN/turnserver_development.conf +++ b/backend/docker/TURN/turnserver_development.conf @@ -23,8 +23,8 @@ lt-cred-mech realm=YourServerPublicIP # TURN server certificate and key (for TLS) certificates are not required in the development environment -# cert=/etc/letsencrypt/live/turn.securityshare.xyz/fullchain.pem -# pkey=/etc/letsencrypt/live/turn.securityshare.xyz/privkey.pem +# cert=/etc/letsencrypt/live/turn.privydrop.app/fullchain.pem +# pkey=/etc/letsencrypt/live/turn.privydrop.app/privkey.pem # Username and password (a more secure method should be used in a production environment) user=UserName:PassWord diff --git a/frontend/app/[lang]/about/page.tsx b/frontend/app/[lang]/about/page.tsx index 365a97a..2ced98b 100644 --- a/frontend/app/[lang]/about/page.tsx +++ b/frontend/app/[lang]/about/page.tsx @@ -13,7 +13,7 @@ export async function generateMetadata({ return { title: messages.meta.about.title, description: messages.meta.about.description, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}/about`, languages: Object.fromEntries( @@ -23,8 +23,8 @@ export async function generateMetadata({ openGraph: { title: messages.meta.about.title, description: messages.meta.about.description, - url: `https://www.securityshare.xyz/${params.lang}/about`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}/about`, + siteName: "PrivyDrop", locale: params.lang, type: "website", }, diff --git a/frontend/app/[lang]/blog/[slug]/metadata.ts b/frontend/app/[lang]/blog/[slug]/metadata.ts index 0d46230..cac3ed9 100644 --- a/frontend/app/[lang]/blog/[slug]/metadata.ts +++ b/frontend/app/[lang]/blog/[slug]/metadata.ts @@ -17,12 +17,12 @@ export async function generateMetadata({ } return { - title: `${post.frontmatter.title} | SecureShare Blog`, + title: `${post.frontmatter.title} | PrivyDrop Blog`, description: post.frontmatter.description, keywords: `${post.frontmatter.tags.join( ", " )}, secure file sharing, p2p transfer, privacy`, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}/blog/${params.slug}`, languages: { @@ -33,8 +33,8 @@ export async function generateMetadata({ openGraph: { title: post.frontmatter.title, description: post.frontmatter.description, - url: `https://www.securityshare.xyz/${params.lang}/blog/${params.slug}`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}/blog/${params.slug}`, + siteName: "PrivyDrop", locale: params.lang, type: "article", publishedTime: post.frontmatter.date, diff --git a/frontend/app/[lang]/blog/metadata.ts b/frontend/app/[lang]/blog/metadata.ts index c59f0ad..d5ecf7f 100644 --- a/frontend/app/[lang]/blog/metadata.ts +++ b/frontend/app/[lang]/blog/metadata.ts @@ -7,12 +7,12 @@ export async function generateMetadata({ params: { lang: string }; }): Promise { return { - title: "SecureShare Blog - Private P2P File Sharing & Collaboration", + title: "PrivyDrop Blog - Private P2P File Sharing & Collaboration", description: "Discover secure file sharing tips, privacy-focused collaboration strategies, and how to leverage P2P technology for safer data transfer. Learn about WebRTC, end-to-end encryption, and team collaboration.", keywords: "secure file sharing, p2p file transfer, private collaboration, webrtc, end-to-end encryption, team collaboration, privacy tools", - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}/blog`, languages: { @@ -21,11 +21,11 @@ export async function generateMetadata({ }, }, openGraph: { - title: "SecureShare Blog - Private P2P File Sharing & Collaboration", + title: "PrivyDrop Blog - Private P2P File Sharing & Collaboration", description: "Explore secure file sharing, private collaboration tools, and data privacy best practices. Join our community of privacy-conscious professionals.", - url: `https://www.securityshare.xyz/${params.lang}/blog`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}/blog`, + siteName: "PrivyDrop", locale: params.lang, type: "website", }, diff --git a/frontend/app/[lang]/blog/tag/[tag]/page.tsx b/frontend/app/[lang]/blog/tag/[tag]/page.tsx index 57e3fe3..63515bd 100644 --- a/frontend/app/[lang]/blog/tag/[tag]/page.tsx +++ b/frontend/app/[lang]/blog/tag/[tag]/page.tsx @@ -12,10 +12,10 @@ export async function generateMetadata({ const decodedTag = unslugifyTag(tag); return { - title: `${decodedTag} - SecureShare Blog Articles`, + title: `${decodedTag} - PrivyDrop Blog Articles`, description: `Explore articles about ${decodedTag} - Learn about secure file sharing, private collaboration, and data privacy solutions related to ${decodedTag}`, keywords: `${decodedTag}, secure file sharing, p2p file transfer, privacy, collaboration, webrtc`, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${lang}/blog/tag/${encodeURIComponent(tag)}`, languages: { @@ -24,12 +24,12 @@ export async function generateMetadata({ }, }, openGraph: { - title: `${decodedTag} - SecureShare Blog Articles`, + title: `${decodedTag} - PrivyDrop Blog Articles`, description: `Discover articles about ${decodedTag} - Expert insights on secure file sharing and private collaboration solutions`, - url: `https://www.securityshare.xyz/${lang}/blog/tag/${encodeURIComponent( + url: `https://www.privydrop.app/${lang}/blog/tag/${encodeURIComponent( tag )}`, - siteName: "SecureShare", + siteName: "PrivyDrop", locale: lang, type: "website", }, diff --git a/frontend/app/[lang]/faq/page.tsx b/frontend/app/[lang]/faq/page.tsx index 0171cab..13297e1 100644 --- a/frontend/app/[lang]/faq/page.tsx +++ b/frontend/app/[lang]/faq/page.tsx @@ -14,7 +14,7 @@ export async function generateMetadata({ title: messages.meta.faq.title, description: messages.meta.faq.description, keywords: messages.meta.faq.keywords, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}/faq`, languages: Object.fromEntries( @@ -24,8 +24,8 @@ export async function generateMetadata({ openGraph: { title: messages.meta.faq.title, description: messages.meta.faq.description, - url: `https://www.securityshare.xyz/${params.lang}/faq`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}/faq`, + siteName: "PrivyDrop", locale: params.lang, type: "website", }, diff --git a/frontend/app/[lang]/help/HelpContent.tsx b/frontend/app/[lang]/help/HelpContent.tsx index c64faf8..d5179e0 100644 --- a/frontend/app/[lang]/help/HelpContent.tsx +++ b/frontend/app/[lang]/help/HelpContent.tsx @@ -32,8 +32,8 @@ export default function HelpContent({ messages, lang }: HelpContentProps) { Twitter - {/*
  • Facebook
  • -
  • LinkedIn
  • */} + {/*
  • Facebook
  • +
  • LinkedIn
  • */}

    {messages.text.help.h2_3}

    diff --git a/frontend/app/[lang]/help/page.tsx b/frontend/app/[lang]/help/page.tsx index 511e8e7..7a8d0e8 100644 --- a/frontend/app/[lang]/help/page.tsx +++ b/frontend/app/[lang]/help/page.tsx @@ -13,7 +13,7 @@ export async function generateMetadata({ return { title: messages.meta.help.title, description: messages.meta.help.description, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}/help`, languages: Object.fromEntries( @@ -23,8 +23,8 @@ export async function generateMetadata({ openGraph: { title: messages.meta.help.title, description: messages.meta.help.description, - url: `https://www.securityshare.xyz/${params.lang}/help`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}/help`, + siteName: "PrivyDrop", locale: params.lang, type: "website", }, diff --git a/frontend/app/[lang]/page.tsx b/frontend/app/[lang]/page.tsx index 422fdc7..3b81683 100644 --- a/frontend/app/[lang]/page.tsx +++ b/frontend/app/[lang]/page.tsx @@ -14,7 +14,7 @@ export async function generateMetadata({ title: messages.meta.home.title, description: messages.meta.home.description, keywords: messages.meta.home.keywords, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}`, languages: Object.fromEntries( @@ -25,8 +25,8 @@ export async function generateMetadata({ openGraph: { title: messages.meta.home.title, description: messages.meta.home.description, - url: `https://www.securityshare.xyz/${params.lang}`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}`, + siteName: "PrivyDrop", locale: params.lang, type: "website", }, diff --git a/frontend/app/[lang]/privacy/page.tsx b/frontend/app/[lang]/privacy/page.tsx index dfa948e..50617d2 100644 --- a/frontend/app/[lang]/privacy/page.tsx +++ b/frontend/app/[lang]/privacy/page.tsx @@ -13,7 +13,7 @@ export async function generateMetadata({ return { title: messages.meta.privacy.title, description: messages.meta.privacy.description, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}/privacy`, languages: Object.fromEntries( @@ -23,8 +23,8 @@ export async function generateMetadata({ openGraph: { title: messages.meta.privacy.title, description: messages.meta.privacy.description, - url: `https://www.securityshare.xyz/${params.lang}/privacy`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}/privacy`, + siteName: "PrivyDrop", locale: params.lang, type: "website", }, diff --git a/frontend/app/[lang]/terms/page.tsx b/frontend/app/[lang]/terms/page.tsx index 81e36d0..a6e3063 100644 --- a/frontend/app/[lang]/terms/page.tsx +++ b/frontend/app/[lang]/terms/page.tsx @@ -13,7 +13,7 @@ export async function generateMetadata({ return { title: messages.meta.terms.title, description: messages.meta.terms.description, - metadataBase: new URL("https://www.securityshare.xyz"), + metadataBase: new URL("https://www.privydrop.app"), alternates: { canonical: `/${params.lang}/terms`, languages: Object.fromEntries( @@ -23,8 +23,8 @@ export async function generateMetadata({ openGraph: { title: messages.meta.terms.title, description: messages.meta.terms.description, - url: `https://www.securityshare.xyz/${params.lang}/terms`, - siteName: "SecureShare", + url: `https://www.privydrop.app/${params.lang}/terms`, + siteName: "PrivyDrop", locale: params.lang, type: "website", }, diff --git a/frontend/app/sitemap.ts b/frontend/app/sitemap.ts index 9193584..06ca11f 100644 --- a/frontend/app/sitemap.ts +++ b/frontend/app/sitemap.ts @@ -2,7 +2,7 @@ import { MetadataRoute } from "next"; import { supportedLocales } from "@/constants/i18n-config"; export default async function sitemap(): Promise { - const baseUrl = "https://www.securityshare.xyz"; + const baseUrl = "https://www.privydrop.app"; const languages = supportedLocales; const routes = ["", "/about", "/help", "/faq", "/terms", "/privacy"]; diff --git a/frontend/components/web/Footer.tsx b/frontend/components/web/Footer.tsx index 3fcd2a6..77f9605 100644 --- a/frontend/components/web/Footer.tsx +++ b/frontend/components/web/Footer.tsx @@ -17,7 +17,7 @@ export function Footer({ messages, lang }: FooterProps) {
    SecureShare Logo { SecureShare Logo - SecureShare + PrivyDrop diff --git a/frontend/components/web/HowItWorks.tsx b/frontend/components/web/HowItWorks.tsx index 7771c9b..0ecbd90 100644 --- a/frontend/components/web/HowItWorks.tsx +++ b/frontend/components/web/HowItWorks.tsx @@ -73,7 +73,7 @@ export default function HowItWorks({ messages }: PageContentProps) { {/* The default Next.js image optimizer does not support handling of GIF animations */} How SecureShare Works SecureShare system diagram: Peer-to-peer file and clipboard sharing**SecureShare**](https://www.securityshare.xyz)) features several notable characteristics: +Our developed tool([**PrivyDrop**](https://www.privydrop.app)) features several notable characteristics: - Device-to-device direct transfer using WebRTC technology, eliminating the need for intermediate servers - End-to-end encryption (E2EE) ensuring secure data transmission @@ -34,14 +34,15 @@ WebRTC (Web Real-Time Communication) is an open standard supporting real-time co ### 1.1 Traditional vs WebRTC Approach -| Feature | Traditional HTTP Transfer | WebRTC P2P Transfer | -|---------|-------------------------|-------------------| -| Transfer Path | Client → Server → Client | Direct Device-to-Device | -| Latency | Limited by central server bandwidth | Limited only by physical network bandwidth | -| File Size Limit | Usually restricted | Limited only by disk space | -| Privacy Protection | Depends on service provider security | Mandatory encryption via DTLS protocol | +| Feature | Traditional HTTP Transfer | WebRTC P2P Transfer | +| ------------------ | ------------------------------------ | ------------------------------------------ | +| Transfer Path | Client → Server → Client | Direct Device-to-Device | +| Latency | Limited by central server bandwidth | Limited only by physical network bandwidth | +| File Size Limit | Usually restricted | Limited only by disk space | +| Privacy Protection | Depends on service provider security | Mandatory encryption via DTLS protocol | ### 1.2 P2P Connection Establishment Process + ```mermaid sequenceDiagram participant UserA as User A (Sender) @@ -86,6 +87,7 @@ WebRTC's **DataChannel** is based on the **Stream Control Transmission Protocol - **Flexible Reliability**: While UDP itself is unreliable, SCTP implements reliable transmission mechanisms on top of it, combining UDP's flexibility with TCP's reliability. **SCTP Multi-Stream Transfer Diagram** + ```mermaid graph TD A[Sender] --> B[DataChannel 1] @@ -99,6 +101,7 @@ D --> E ## II. Browser Direct Transfer Engine: Core Technology Decoded ### 2.1 Precise Control of Chunk Transfer + ```typescript // lib/fileSender.ts - 64KB Fixed-Size Chunks @@ -110,15 +113,15 @@ private readonly CHUNK_SIZE = 65536; // Each generator call returns an ArrayBuffer type chunk data. private async *createChunkGenerator(file: File) { let offset = 0; // Initialize offset to mark current file reading position - + // Loop through file until all data is processed while (offset < file.size) { // Use File.slice method to extract data segment from [offset, offset + CHUNK_SIZE) const chunk = file.slice(offset, offset + this.CHUNK_SIZE); - + // Convert extracted data to ArrayBuffer and return via yield yield await chunk.arrayBuffer(); - + // Update offset for next chunk offset += this.CHUNK_SIZE; } @@ -132,14 +135,16 @@ private async sendWithBackpressure(chunk: ArrayBuffer) { // Use Promise to wait for bufferedamountlow event indicating buffer space freed await new Promise(r => this.dataChannel.bufferedamountlow = r); } - + // Send current chunk when buffer has sufficient space this.dataChannel.send(chunk); } ``` ### 2.2 Zero-Copy Memory Writing + Implemented through File System Access API: + ```typescript // lib/fileReceiver.ts @@ -149,11 +154,11 @@ private async writeToDisk(chunk: ArrayBuffer) { if (!this.writer) { // Show save file picker dialog for user to choose save location this.currentFileHandle = await window.showSaveFilePicker(); - + // Create writable stream through file handle for subsequent writes this.writer = await this.currentFileHandle.createWritable(); } - + // Convert received ArrayBuffer to Uint8Array and write directly to disk // This bypasses memory buffer, achieving zero-copy writing for improved performance await this.writer.write(new Uint8Array(chunk)); @@ -163,28 +168,33 @@ private async writeToDisk(chunk: ArrayBuffer) { ## III. Distributed Room Management System ### 3.1 Four-Digit Collision Detection: + ```typescript // server.ts async function getAvailableRoomId() { let roomId; do { roomId = Math.floor(1000 + Math.random() * 9000); // Generate four-digit random number - } while (await redis.hexists(`room:${roomId}`, 'created_at')); // Check if exists + } while (await redis.hexists(`room:${roomId}`, "created_at")); // Check if exists return roomId; } ``` + Note: The 4-digit number is a system-generated random room ID. You can specify any room ID you prefer. ### 3.2 Graceful Expiration Strategy: + ```typescript // server.ts await refreshRoom(roomId, 3600 * 24); // Active rooms retained for 24 hours -if (await isRoomEmpty(roomId)) { // Release room if idle (both sender and receiver left) +if (await isRoomEmpty(roomId)) { + // Release room if idle (both sender and receiver left) await deleteRoom(roomId); } ``` ### 3.3 Signaling-Driven Recovery Protocol + Mobile Disconnection Recovery Flow: ```mermaid @@ -192,7 +202,7 @@ sequenceDiagram participant Sender participant Signaling participant Recipient - + Sender->>Signaling: Send initiator-online when frontend visible Signaling->>Recipient: Forward online notification Recipient->>Signaling: Reply recipient-ready @@ -217,49 +227,51 @@ Through this mechanism, the system can quickly restore connections even when use **Explanation:** 1. **DTLS (Datagram Transport Layer Security)**: - - DTLS is a UDP-based secure transport protocol providing TLS-like encryption. - - In WebRTC, all data channels are end-to-end encrypted via DTLS, preventing eavesdropping or tampering during transmission. - - Uses encryption suite **`TLS_ECDHE_RSA_AES_128_GCM_SHA256`** for high-strength security. + - DTLS is a UDP-based secure transport protocol providing TLS-like encryption. + - In WebRTC, all data channels are end-to-end encrypted via DTLS, preventing eavesdropping or tampering during transmission. + - Uses encryption suite **`TLS_ECDHE_RSA_AES_128_GCM_SHA256`** for high-strength security. 2. **OS-Level Encryption**: - - Modern browsers provide additional protection for sensitive data in memory at the OS level, preventing malicious software access. + - Modern browsers provide additional protection for sensitive data in memory at the OS level, preventing malicious software access. **Summary:** Through dual protection of DTLS and OS-level encryption, WebRTC provides robust privacy protection ensuring data security during file transfer. ### 4.2 Attack Surface Defense Matrix -| **Attack Type** | **Defense Measure** | **Explanation** | -| --- | --- | --- | -| **MITM** | **SDP Fingerprint Verification** | **Generates unique fingerprint from DTLS public key hash to ensure communication party identity, preventing middleman data stream forgery or tampering.** | -| **RoomID Traversal Attack** | **Room Entry Rate Limiting** | **Limits room entry frequency per IP address (e.g., max 2 joins per 5 seconds) to prevent malicious users from traversing room numbers to access content.** | +| **Attack Type** | **Defense Measure** | **Explanation** | +| --------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **MITM** | **SDP Fingerprint Verification** | **Generates unique fingerprint from DTLS public key hash to ensure communication party identity, preventing middleman data stream forgery or tampering.** | +| **RoomID Traversal Attack** | **Room Entry Rate Limiting** | **Limits room entry frequency per IP address (e.g., max 2 joins per 5 seconds) to prevent malicious users from traversing room numbers to access content.** | **Explanation:** + 1. **MITM (Man-in-the-Middle Attack)** - - **Principle**: WebRTC uses SDP fingerprints (based on DTLS public key hash) to verify communication party identity during handshake. Attackers cannot forge valid fingerprints, thus cannot impersonate legitimate parties. - - **Effect**: Ensures P2P connection security and data integrity, preventing eavesdropping or tampering. + - **Principle**: WebRTC uses SDP fingerprints (based on DTLS public key hash) to verify communication party identity during handshake. Attackers cannot forge valid fingerprints, thus cannot impersonate legitimate parties. + - **Effect**: Ensures P2P connection security and data integrity, preventing eavesdropping or tampering. 2. **RoomID Traversal Attack** - - **Definition**: Malicious users might attempt different room numbers (e.g., four-digit IDs) to enter unauthorized rooms and access shared content. - - **Defense Measures**: - - **Rate Limiting**: Restrict room entry frequency per IP address, e.g., max 2 room joins per 5 seconds. - - **Implementation**: Use Redis to cache IP request records for quick detection and blocking of abnormal behavior. - - **Effect**: Effectively prevents malicious users from accessing sensitive content through room number traversal, protecting user privacy. + - **Definition**: Malicious users might attempt different room numbers (e.g., four-digit IDs) to enter unauthorized rooms and access shared content. + - **Defense Measures**: + - **Rate Limiting**: Restrict room entry frequency per IP address, e.g., max 2 room joins per 5 seconds. + - **Implementation**: Use Redis to cache IP request records for quick detection and blocking of abnormal behavior. + - **Effect**: Effectively prevents malicious users from accessing sensitive content through room number traversal, protecting user privacy. ## Conclusion: Building Trustworthy Transfer Infrastructure -We believe technology should serve essential human needs rather than create new surveillance dependencies. Experience this privacy-secure file transfer tool now and feel the revolutionary changes brought by P2P technology! Click [**SecureShare Portal**](https://www.securityshare.xyz) to begin. +We believe technology should serve essential human needs rather than create new surveillance dependencies. Experience this privacy-secure file transfer tool now and feel the revolutionary changes brought by P2P technology! Click [**PrivyDrop Portal**](https://www.privydrop.app) to begin. **Code Transparency Commitment**: Code will be open-sourced in the future. We are committed to establishing truly trustworthy privacy tools through community co-governance. ## FAQ - - **Will large file transfers be prone to interruption?** - - Haven't observed such cases yet. P2P (device-to-device) connections are generally stable. We may add resume-from-breakpoint capability based on future feedback. - - **Would adding room passwords be more secure?** - - Theoretically yes. Considering password addition would slightly impact usability, it's not implemented yet. For enhanced security, you can use any custom string as RoomID and share via links and QR codes. Additionally, the system limits receiver room entry frequency, further improving security. - - **Can senders close the SecureShare page anytime?** - - Yes, preferably after content is received. Since it's direct device connection, sharing isn't possible if sender is offline. If you want to stop sharing, you can close the page immediately. +- **Will large file transfers be prone to interruption?** + - Haven't observed such cases yet. P2P (device-to-device) connections are generally stable. We may add resume-from-breakpoint capability based on future feedback. +- **Would adding room passwords be more secure?** + - Theoretically yes. Considering password addition would slightly impact usability, it's not implemented yet. For enhanced security, you can use any custom string as RoomID and share via links and QR codes. Additionally, the system limits receiver room entry frequency, further improving security. +- **Can senders close the PrivyDrop page anytime?** + - Yes, preferably after content is received. Since it's direct device connection, sharing isn't possible if sender is offline. If you want to stop sharing, you can close the page immediately. - More questions? Click [**SecureShare FAQ**](https://www.securityshare.xyz/faq) or [**SecureShare Help**](https://www.securityshare.xyz/help) sections for more answers and help. +More questions? Click [**PrivyDrop FAQ**](https://www.privydrop.app/faq) or [**PrivyDrop Help**](https://www.privydrop.app/help) sections for more answers and help. **Developer Resources** + - [**WebRTC Official Documentation**](https://webrtc.org/) diff --git a/frontend/content/blog/webRTC-file-transfer-zh.mdx b/frontend/content/blog/webRTC-file-transfer-zh.mdx index 1b76b48..7f713a8 100644 --- a/frontend/content/blog/webRTC-file-transfer-zh.mdx +++ b/frontend/content/blog/webRTC-file-transfer-zh.mdx @@ -7,39 +7,42 @@ cover: "/blog-assets/webrtc-file-transfer.jpg" tags: [WebRTC, P2P传输, 隐私安全] status: "published" --- + ![](/blog-assets/webrtc-file-transfer.jpg) ## 引言 + 传统的文件传输方式大多依赖云存储或中心化服务器,这不仅带来了数据隐私的顾虑,还可能面临上传大小限制、速度瓶颈等诸多问题。而我们的工具通过 WebRTC 技术实现了设备间的直接传输,彻底解决了这些问题。 -我们开发的这款工具([**SecureShare**](https://www.securityshare.xyz))具有以下突出特点: +我们开发的这款工具([**PrivyDrop**](https://www.privydrop.app))具有以下突出特点: -- 采用WebRTC技术实现设备间直接传输,无需经过中间服务器 +- 采用 WebRTC 技术实现设备间直接传输,无需经过中间服务器 - 端到端加密(E2EE)确保数据传输安全 - 无需注册登录,即开即用,可多人同时接收 - 支持文本、图片、文件、文件夹等多种类型的数据传输 - 传输速度和文件大小仅受限于设备间的网络带宽和磁盘空间 -在这篇文章中,我们将深入探讨这款工具的技术架构、工作原理以及它为什么能够提供如此安全和高效的文件传输体验。无论您是技术爱好者还是普通用户,都能从中了解到WebRTC技术在文件传输领域带来的革命性变化。 +在这篇文章中,我们将深入探讨这款工具的技术架构、工作原理以及它为什么能够提供如此安全和高效的文件传输体验。无论您是技术爱好者还是普通用户,都能从中了解到 WebRTC 技术在文件传输领域带来的革命性变化。 ## 一、重新定义文件传输:WebRTC 的架构革命 -WebRTC(Web Real-Time Communication)是一种支持浏览器之间实时通信的开放标准。我们的文件传输工具基于WebRTC开发,主要包含以下几个核心组件: +WebRTC(Web Real-Time Communication)是一种支持浏览器之间实时通信的开放标准。我们的文件传输工具基于 WebRTC 开发,主要包含以下几个核心组件: 1. **信令服务器**:用于协调设备之间的连接,但不参与实际数据传输。 -2. **P2P连接**:设备之间直接建立连接,数据不经过第三方服务器。 -3. **E2EE加密**:所有数据在传输过程中使用DTLS协议进行端到端加密。 +2. **P2P 连接**:设备之间直接建立连接,数据不经过第三方服务器。 +3. **E2EE 加密**:所有数据在传输过程中使用 DTLS 协议进行端到端加密。 ### 1.1 传统方案 vs WebRTC 方案 -| 特性 | 传统 HTTP 传输 | WebRTC P2P 传输 | -|--------------------|-------------------------|-------------------------| -| 传输路径 | 客户端→服务器→客户端 | 端到端直连 | -| 延时特性 | 受中心服务器带宽限制 | 仅受网络物理带宽限制 | -| 文件大小限制 | 通常有一定的限制 | 仅受磁盘空间限制 | -| 隐私保护 | 依赖服务商安全措施 | DTLS 协议强制加密 | +| 特性 | 传统 HTTP 传输 | WebRTC P2P 传输 | +| ------------ | ------------------------ | -------------------- | +| 传输路径 | 客户端 → 服务器 → 客户端 | 端到端直连 | +| 延时特性 | 受中心服务器带宽限制 | 仅受网络物理带宽限制 | +| 文件大小限制 | 通常有一定的限制 | 仅受磁盘空间限制 | +| 隐私保护 | 依赖服务商安全措施 | DTLS 协议强制加密 | + +### 1.2 建立 P2P 连接的流程 -### 1.2 建立P2P连接的流程 ```mermaid sequenceDiagram participant UserA as 用户A(发送方) @@ -61,12 +64,13 @@ sequenceDiagram UserA-->>UserB: (5) 建立P2P连接(DataChannel) UserA->>UserB: (6) 文件分块传输通过DataChannel ``` + **流程:** -1. 用户A创建房间并加入,连接到信令服务器。 -2. 用户B加入房间后,也连接到信令服务器。 -3. 用户A开始与用户B发起 WebRTC 协商(包括 SDP 和 ICE 信息)。 -4. 用户B响应 WebRTC 协商信息,完成 P2P 连接的建立。 +1. 用户 A 创建房间并加入,连接到信令服务器。 +2. 用户 B 加入房间后,也连接到信令服务器。 +3. 用户 A 开始与用户 B 发起 WebRTC 协商(包括 SDP 和 ICE 信息)。 +4. 用户 B 响应 WebRTC 协商信息,完成 P2P 连接的建立。 5. 最终,文件通过 DataChannel 在 P2P 连接上传输。 ### 1.3 SCTP(over DTLS & UDP) 协议的性能魔法 @@ -83,6 +87,7 @@ WebRTC 的 **DataChannel** 基于 **流控制传输协议 (SCTP)** ,运行在 - **灵活可靠** :虽然 UDP 本身不可靠,但 SCTP 在其基础上实现了可靠的传输机制,结合了 UDP 的灵活性和 TCP 的可靠性。 **SCTP 多流传输示意图** + ```mermaid graph TD A[发送方] --> B[DataChannel 1] @@ -92,8 +97,11 @@ B --> E[接收方] C --> E D --> E ``` + ## 二、浏览器直传引擎:核心技术解密 + ### 2.1 分片传输的精密控制 + ```typescript // lib/fileSender.ts - 64KB 定长分片 @@ -105,15 +113,15 @@ private readonly CHUNK_SIZE = 65536; // 每次调用生成器时,返回一个 ArrayBuffer 类型的分片数据。 private async *createChunkGenerator(file: File) { let offset = 0; // 初始化偏移量,用于标记当前读取到文件的位置。 - + // 循环读取文件,直到所有数据都被分片处理完毕。 while (offset < file.size) { // 使用 File.slice 方法从文件中截取一段数据,范围为 [offset, offset + CHUNK_SIZE)。 const chunk = file.slice(offset, offset + this.CHUNK_SIZE); - + // 将截取的数据转换为 ArrayBuffer,并通过 yield 返回给调用者。 yield await chunk.arrayBuffer(); - + // 更新偏移量,准备处理下一个分片。 offset += this.CHUNK_SIZE; } @@ -127,13 +135,16 @@ private async sendWithBackpressure(chunk: ArrayBuffer) { // 使用 Promise 等待 bufferedamountlow 事件触发,表示缓冲区空间已释放。 await new Promise(r => this.dataChannel.bufferedamountlow = r); } - + // 缓冲区有足够空间后,发送当前分片数据。 this.dataChannel.send(chunk); } ``` + ### 2.2 内存零拷贝写入 + 通过 File System Access API 实现: + ```typescript // lib/fileReceiver.ts @@ -143,19 +154,23 @@ private async writeToDisk(chunk: ArrayBuffer) { if (!this.writer) { // 使用 showSaveFilePicker 弹出文件保存对话框,让用户选择保存位置。 this.currentFileHandle = await window.showSaveFilePicker(); - + // 通过文件句柄创建一个可写流(WritableStream),用于后续写入操作。 this.writer = await this.currentFileHandle.createWritable(); } - + // 将接收到的 ArrayBuffer 数据转换为 Uint8Array 格式,并直接写入磁盘。 // 这种方式绕过了内存缓冲区,实现了零拷贝写入,提升了性能。 await this.writer.write(new Uint8Array(chunk)); } ``` + ## 三、分布式房间管理系统 + ### 3.1 四位数字碰撞检测: + 碰撞检测 :通过循环检查 Redis 中是否存在相同的房间号,避免重复。 + ```typescript // server.ts async function getAvailableRoomId() { @@ -166,18 +181,24 @@ roomId = Math.floor(1000 + Math.random() * 9000); // 生成四位随机数 return roomId; } ``` -ps:4位数字是系统生成的一个随机房间ID,你也可以指定任意自己喜欢的房间ID. + +ps:4 位数字是系统生成的一个随机房间 ID,你也可以指定任意自己喜欢的房间 ID. ### 3.2 优雅过期策略: + 优雅过期 :活跃房间会自动延长过期时间,而空闲房间会被及时清理,节省资源。 + ```typescript // server.ts await refreshRoom(roomId, 3600 * 24); // 活跃房间保留24小时 -if (await isRoomEmpty(roomId)) { // 如果房间空闲(发送方、接收方都退出了),则释放房间 +if (await isRoomEmpty(roomId)) { + // 如果房间空闲(发送方、接收方都退出了),则释放房间 await deleteRoom(roomId); } ``` + ### 3.3 信令驱动的重生协议 + 移动端断线恢复流程: ```mermaid @@ -185,16 +206,18 @@ sequenceDiagram participant Sender participant Signaling participant Recipient - + Sender->>Signaling: 前端可见时发 initiator-online Signaling->>Recipient: 转发上线通知 - Recipient->>Signaling: 回复recipient-ready + Recipient->>Signaling: 回复recipient-ready Signaling->>Sender: 触发重连流程 Sender->>Recipient: 重建 ICE 连接 ``` -通过这一机制,即使用户在移动设备上切换应用或进入后台,系统也能快速恢复连接(移动端也加入了Wakelock防休眠),确保良好的用户体验。 + +通过这一机制,即使用户在移动设备上切换应用或进入后台,系统也能快速恢复连接(移动端也加入了 Wakelock 防休眠),确保良好的用户体验。 ## 四、安全隐私防线 + ### 4.1 加密协议飞轮 ``` @@ -204,53 +227,55 @@ sequenceDiagram ↑ 操作系统级加密 ``` + **解释:** 1. **DTLS(Datagram Transport Layer Security)** : - - DTLS 是基于 UDP 的安全传输协议,提供类似于 TLS 的加密功能。 - - 在 WebRTC 中,所有数据通道(DataChannel)都通过 DTLS 进行端到端加密,确保数据在传输过程中无法被窃听或篡改。 - - 使用的加密套件为 **`TLS_ECDHE_RSA_AES_128_GCM_SHA256`**,提供高强度的安全性。 + - DTLS 是基于 UDP 的安全传输协议,提供类似于 TLS 的加密功能。 + - 在 WebRTC 中,所有数据通道(DataChannel)都通过 DTLS 进行端到端加密,确保数据在传输过程中无法被窃听或篡改。 + - 使用的加密套件为 **`TLS_ECDHE_RSA_AES_128_GCM_SHA256`**,提供高强度的安全性。 2. **操作系统级加密** : - - 在操作系统层面,现代浏览器会对内存中的敏感数据进行额外保护,防止恶意软件访问。 + - 在操作系统层面,现代浏览器会对内存中的敏感数据进行额外保护,防止恶意软件访问。 **总结:** 通过 DTLS 和操作系统级加密的双重保障,WebRTC 提供了强大的隐私保护能力,确保文件传输过程中的数据安全。 - ### 4.2 攻击面防御矩阵 -| **攻击类型** | **防御措施** | **解释** | -| --- | --- | --- | -| **MITM** | **SDP 指纹校验** | **通过 DTLS 公钥哈希值生成唯一指纹,确保通信双方身份可信,防止中间人伪造或篡改数据流。** | +| **攻击类型** | **防御措施** | **解释** | +| ------------------ | -------------------- | ---------------------------------------------------------------------------------------------------- | +| **MITM** | **SDP 指纹校验** | **通过 DTLS 公钥哈希值生成唯一指纹,确保通信双方身份可信,防止中间人伪造或篡改数据流。** | | **房间号遍历攻击** | **进入房间速率限制** | **对每个 IP 地址的进入房间频率进行限制(如 5 秒内最多加入 2 次),防止恶意用户遍历房间号获取内容。** | **解释:** + 1. **MITM(中间人攻击)** - - **原理** :WebRTC 使用 SDP 指纹(基于 DTLS 公钥哈希值)在握手过程中验证通信双方的身份。攻击者无法伪造合法的指纹,因此无法伪装成合法通信方。 - - **作用** :确保 P2P 连接的安全性和数据完整性,防止数据被窃听或篡改。 + - **原理** :WebRTC 使用 SDP 指纹(基于 DTLS 公钥哈希值)在握手过程中验证通信双方的身份。攻击者无法伪造合法的指纹,因此无法伪装成合法通信方。 + - **作用** :确保 P2P 连接的安全性和数据完整性,防止数据被窃听或篡改。 2. **房间号遍历攻击** - - **定义** :恶意用户可能通过暴力尝试不同的房间号(例如四位数字 ID),试图进入未授权的房间并获取分享内容。 - - **防御措施** : - - **速率限制** :对每个 IP 地址的进入房间频率进行限制,例如 5 秒内最多允许加入 2 次房间。 - - **实现方式** :使用 Redis 缓存每个 IP 的请求记录,快速检测和阻止异常行为。 - - **作用** :有效防止恶意用户通过遍历房间号获取敏感内容,保护用户隐私。 + - **定义** :恶意用户可能通过暴力尝试不同的房间号(例如四位数字 ID),试图进入未授权的房间并获取分享内容。 + - **防御措施** : + - **速率限制** :对每个 IP 地址的进入房间频率进行限制,例如 5 秒内最多允许加入 2 次房间。 + - **实现方式** :使用 Redis 缓存每个 IP 的请求记录,快速检测和阻止异常行为。 + - **作用** :有效防止恶意用户通过遍历房间号获取敏感内容,保护用户隐私。 ## 结语:打造可信赖的传输基础设施 -我们坚信技术应该服务于人的本质需求,而非制造新的监控依赖。立即体验这款隐私安全的文件传输工具,感受 P2P 技术带来的革命性变化!点击[**SecureShare入口**](https://www.securityshare.xyz)开始 。 +我们坚信技术应该服务于人的本质需求,而非制造新的监控依赖。立即体验这款隐私安全的文件传输工具,感受 P2P 技术带来的革命性变化!点击[**PrivyDrop 入口**](https://www.privydrop.app)开始 。 **代码透明度承诺**:代码未来会开源,我们致力于通过社区共治建立真正值得信赖的隐私工具。 ## 常见问题 - - **传大文件会不会容易中断?** - - 暂时没发现这种情况。由于是P2P(设备间)连接,一般比较稳定。后面可以看反馈情况择机加入断点续传。 - - **房间加上密码更安全?** - - 理论上是的。考虑到加密码易用性上体验会差点,暂时没有加。如果想提高安全性,可以自定义任意长度的字符串作为RoomID,同时通过链接和二维码进行分享。另外,系统对接收方进入房间的频率进行了限制,此举进一步提高了安全性。 - - **发送方可以随时关闭SecureShare页面吗?** - - 可以,最好在分享内容被接收之后再关闭。因为是设备间直接连接,发送方如果不在线,则无法进行分享。如果不想分享了,可以立即关闭页面。 +- **传大文件会不会容易中断?** + - 暂时没发现这种情况。由于是 P2P(设备间)连接,一般比较稳定。后面可以看反馈情况择机加入断点续传。 +- **房间加上密码更安全?** + - 理论上是的。考虑到加密码易用性上体验会差点,暂时没有加。如果想提高安全性,可以自定义任意长度的字符串作为 RoomID,同时通过链接和二维码进行分享。另外,系统对接收方进入房间的频率进行了限制,此举进一步提高了安全性。 +- **发送方可以随时关闭 PrivyDrop 页面吗?** + - 可以,最好在分享内容被接收之后再关闭。因为是设备间直接连接,发送方如果不在线,则无法进行分享。如果不想分享了,可以立即关闭页面。 - 还有问题?请点击查看[**SecureShare FAQ**](https://www.securityshare.xyz/faq)或[**SecureShare Help**](https://www.securityshare.xyz/help)部分。 +还有问题?请点击查看[**PrivyDrop FAQ**](https://www.privydrop.app/faq)或[**PrivyDrop Help**](https://www.privydrop.app/help)部分。 **开发者资源** -- [**WebRTC 官方文档**](https://webrtc.org/) \ No newline at end of file + +- [**WebRTC 官方文档**](https://webrtc.org/) diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt index 6344c1a..af6ae48 100644 --- a/frontend/public/robots.txt +++ b/frontend/public/robots.txt @@ -2,4 +2,4 @@ User-agent: * Disallow: /api/ Disallow: /*?roomId= Allow: / -Sitemap: https://www.securityshare.xyz/sitemap.xml \ No newline at end of file +Sitemap: https://www.privydrop.app/sitemap.xml \ No newline at end of file