תארו לעצמכם: לקוח חותם על חוזה באמצעות אפליקציה ניידת ומאוחר יותר מערער על האותנטיות שלו. ללא מטא-דאטה ביומטרי, לא ניתן לפתור מחלוקות כאלה. נתקלנו בכך בפרויקט פינטק — נאלצנו לבנות מחדש את מודול החתימה מאפס. הגישה שלנו: שילוב של לכידת מסלול עם לחץ ומהירות, קישור ל-hash של המסמך, ושמירת נתיב ביקורת. אפליקציות ניידות דורשות יותר ויותר מודול חתימה בכתב יד מובנה — ממסמכים בנקאיים ועד רשומות רפואיות. אבל האשליה של "רק תמונה" מסוכנת: לחתימה על המסך אין משקל משפטי ללא קישור לזהות, למסמך ולזמן. אנו פותרים זאת ברמת Android (Kotlin, Jetpack Compose) ו-iOS (Swift, SwiftUI), תוך שימוש בלכידת מסלול ברמה נמוכה ומטא-דאטה ביומטרי. הניסיון שלנו — מעל 10 פרויקטים של שילוב חתימות בזרימות עבודה של מסמכים, המבטיחים פעולה יציבה בכל המכשירים. העלות של פתרון כזה משתלמת על ידי הפחתת הסיכון להתדיינות משפטית.
לכידת החתימה בכתב יד
איסוף המסלול הוא הבסיס. אנו זקוקים לא רק לקואורדינטות touchMove אלא לזרם האירועים המלא עם לחץ, מהירות וחותמות זמן. זה מאפשר שחזור מונפש של החתימה ואיסוף מטא-דאטה ביומטרי.
Android — קלט ברמה נמוכה:
override fun onTouchEvent(event: MotionEvent): Boolean {
val x = event.x
val y = event.y
val pressure = event.pressure // 0.0 - 1.0
val timestamp = event.eventTime
when (event.action) {
MotionEvent.ACTION_DOWN -> startStroke(x, y, pressure, timestamp)
MotionEvent.ACTION_MOVE -> {
for (i in 0 until event.historySize) {
addHistoricalPoint(
event.getHistoricalX(i),
event.getHistoricalY(i),
event.getHistoricalPressure(i),
event.getHistoricalEventTime(i)
)
}
addPoint(x, y, pressure, timestamp)
}
MotionEvent.ACTION_UP -> endStroke(x, y, pressure, timestamp)
}
return true
}override fun onTouchEvent(event: MotionEvent): Boolean { val x = event.x val y = event.y val pressure = event.pressure // 0.0 - 1.0 val timestamp = event.eventTime when (event.action) { MotionEvent.ACTION_DOWN -> startStroke(x, y, pressure, timestamp) MotionEvent.ACTION_MOVE -> { for (i in 0 until event.historySize) { addHistoricalPoint( event.getHistoricalX(i), event.getHistoricalY(i), event.getHistoricalPressure(i), event.getHistoricalEventTime(i) ) } addPoint(x, y, pressure, timestamp) } MotionEvent.ACTION_UP -> endStroke(x, y, pressure, timestamp) } return true } הוא קריטי — בין שני אירועי event.historySize, המערכת מאגדת נקודות ביניים. התעלמות מנקודות היסטוריות מייצרת קווים משוננים במקום עקומות חלקות.
iOS — UIBezierPath עם החלקת Bezier:
func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let currentPoint = touch.location(in: self)
let previousPoint = touch.previousLocation(in: self)
let force = touch.force / touch.maximumPossibleForce
let midPoint = CGPoint(
x: (currentPoint.x + previousPoint.x) / 2,
y: (currentPoint.y + previousPoint.y) / 2
)
path.addQuadCurve(to: midPoint, controlPoint: previousPoint)
setNeedsDisplay()
}עבור Apple Pencil אנו משתמשים ב-ACTION_MOVE — ללא נקודות חזויות, התגובה ב-120 הרץ מרגישה איטית.
עובי קו משתנה
חתימה מקצועית נראית טבעית כאשר עובי הקו משתנה עם לחץ ומהירות. המתמטיקה פשוטה: func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else { return } let currentPoint = touch.location(in: self) let previousPoint = touch.previousLocation(in: self) let force = touch.force / touch.maximumPossibleForce let midPoint = CGPoint( x: (currentPoint.x + previousPoint.x) / 2, y: (currentPoint.y + previousPoint.y) / 2 ) path.addQuadCurve(to: midPoint, controlPoint: previousPoint) setNeedsDisplay() } . במהירות גבוהה — קו דק; בתנועה איטית — עבה.
fun calculateStrokeWidth(pressure: Float, velocity: Float): Float {
val pressureComponent = pressure * MAX_PRESSURE_WIDTH
val velocityComponent = (1f - velocity.coerceIn(0f, 1f)) * MAX_VELOCITY_WIDTH
return BASE_WIDTH + pressureComponent * 0.6f + velocityComponent * 0.4f
} כיצד להבטיח תוקף משפטי? — מטא-דאטה ביומטרי
כדי לחזק את הכוח המשפטי, אנו אוספים מטא-דאטה של תהליך החתימה:
- חותמות זמן של כל משיכה
- מהירות תנועת הקטע
- לחץ (אם המכשיר תומך)
- משך כל משיכה והפסקות ביניהן
- זמן חתימה כולל
מידע נוסף על איסוף מטא-דאטה
כל משיכה נלכדת בדיוק של מילישניות. אנו משתמשים בביומטריה התנהגותית — דפוס הלחץ והמהירות הייחודי קשה לזיוף. ללא נתונים אלה, החתימה היא רק PNG.נתונים אלה נשמרים במסד הנתונים וניתן להשתמש בהם בבית המשפט כדי לערער על אותנטיות החתימה — ביומטריה התנהגותית. בלעדיהם, החתימה היא רק PNG.
קישור למסמך
ציור החתימה לבדו חסר תועלת. אנו צריכים:
- לכידת ה-hash של המסמך לפני החתימה (SHA-256 של PDF או תוכן טקסט)
- צירוף החתימה (PNG + מטא-דאטה של מסלול) ל-hash זה
- שמירה בשרת עם חותמת זמן ומזהה החותם
- אופציונלי: הטמעת החתימה ב-PDF באמצעות iText (Java/Android) או PDFKit (iOS)
רשומת שרת:
{
"document_hash": "sha256:abc123...",
"signer_id": "user-uuid",
"signed_at": "timestamp",
"ip_address": "1.2.3.4",
"device_fingerprint": "...",
"signature_image_url": "...",
"stroke_data_encrypted": "...",
"session_metadata": {
"duration_ms": 4200,
"stroke_count": 5,
"avg_pressure": 0.72
}
} למה לא לחסוך בביומטריה? השוואת גישות
| קריטריון | SDK מוכן (SignaturePad וכו') | יישום מותאם אישית |
|---|---|---|
| זמן אינטגרציה | 1–2 ימים | 3–4 ימים |
| מטא-דאטה ביומטרי | אין | איסוף מלא |
| עובי משתנה עם לחץ | מוגבל | ניתן להתאמה אישית |
| אינטגרציית PKI | לא | אפשרי |
| כוח משפטי | רק EP פשוט | EP מוסמך עם נתיב ביקורת |
SDKs מוכנים מוצדקים לתרחישים פשוטים (EP פשוט), אך אם נדרש EP מוסמך עם אפשרות לערעור בבית משפט, יישום מותאם אישית אמין פי 2–3.
נתוני ביקורת נוספים
| פרמטר | ערך |
|---|---|
| נקודות לחתימה | 500–1500 |
| גודל מטא-דאטה | 2–5 KB |
| דיוק זמן | ±1 אלפית השנייה |
| מכשירים נתמכים | iOS 14+, Android 8+ |
אינטגרציית PDF
ב-iOS: predictedTouches(for:) + width = baseWidth + pressure * maxExtraWidth כדי לצייר את החתימה מעל דף ה-PDF. להטמעה מקצועית עם שדות AcroForm — ספריית צד שלישי fun calculateStrokeWidth(pressure: Float, velocity: Float): Float { val pressureComponent = pressure * MAX_PRESSURE_WIDTH val velocityComponent = (1f - velocity.coerceIn(0f, 1f)) * MAX_VELOCITY_WIDTH return BASE_WIDTH + pressureComponent * 0.6f + velocityComponent * 0.4f } או { "document_hash": "sha256:abc123...", "signer_id": "user-uuid", "signed_at": "timestamp", "ip_address": "1.2.3.4", "device_fingerprint": "...", "signature_image_url": "...", "stroke_data_encrypted": "...", "session_metadata": { "duration_ms": 4200, "stroke_count": 5, "avg_pressure": 0.72 } } בצד השרת באמצעות API.
ב-Android: PDFKit לתצוגה, הטמעה באמצעות CGContext Android או Apache PDFBox.
חשוב: הטמעה ויזואלית של חתימה ב-PDF ≠ חתימה דיגיטלית (PKI). אלה דברים שונים. עבור מסמך PDF מחייב משפטית, נדרשת חתימת PKI — החתימה בכתב יד מתווספת כאלמנט ויזואלי נוסף.
מה כלול בעבודה
בהזמנת פתרון מפתח, אתה מקבל:
- רכיב ציור חתימה ל-iOS ו-Android עם תמיכה בלחץ והחלקה
- מודול שרת לקישור מסמכים (hash, מטא-דאטה, חותמת זמן)
- אינטגרציית PDF (הטמעת חתימה)
- תיעוד API ודוגמאות אינטגרציה
- שבועיים של תמיכה טכנית
אנו מספקים הערכת פרויקט תוך יום אחד. הזמינו יישום מותאם אישית — קבלו שליטה מלאה על ביומטריה. צרו קשר לייעוץ.
לוחות זמנים: 3–4 ימים לפלטפורמה אחת, 5–7 ימים לשתיהן. קבלו ייעוץ.







