كيفية تشفير Java: تشفير XOR مخصص مع GroupDocs
مقدمة
إذا احتجت يوماً إلى how to encrypt java لعملية معينة، فأنت تعرف الإحباط الناتج عن الخيارات المدمجة التي لا تتوافق مع بروتوكولك القديم أو هدف الأداء. تخيّل أنك تقوم بدمج وحدة توقيع جديدة في نظام ERP قديم يتوقع حمولة مُقنَّعة بـ XOR بسيط. يمكنك إعادة كتابة نظام ERP بالكامل، لكن الطريق الأسرع هو إضافة طبقة تشفير مخصصة خفيفة الوزن داخل تطبيق Java الخاص بك.
في هذا الدليل سنستعرض إنشاء آلية تشفير XOR مخصصة، ربطها بـ GroupDocs.Signature for Java، ومناقشة متى يكون هذا النهج مناسبًا ومتى يجب اللجوء إلى الخوارزميات القياسية في الصناعة. في النهاية ستتمكن من حماية بيانات تعريف التوقيع، تلبية العقود المتقلبة للتكامل، وفهم المساومات لاستخدام XOR في شفرة جاهزة للإنتاج.
ما ستتعلمه:
- لماذا التشفير المخصص مهم للأنظمة القديمة وسيناريوهات الأداء
- كيف يعمل تشفير XOR (شرح بسيط + مثال Java)
- دمج خطوة بخطوة مع GroupDocs.Signature for Java
- حالات الاستخدام الواقعية، اعتبارات الأمان، والأخطاء الشائعة
- كيفية استبدال تنفيذ XOR بخوارزمية أقوى لاحقاً
إجابات سريعة
- ما هو تشفير XOR؟ عملية متماثلة تقلب البتات باستخدام مفتاح؛ التشفير مرتين بالمفتاح نفسه يعيد البيانات الأصلية.
- متى يجب استخدام تشفير مخصص؟ لتوافق الأنظمة القديمة، إخفاء الأداء الحرج، أو لأغراض التعلم — ليس لحماية البيانات الحساسة.
- أي مكتبة يستخدم هذا الدرس؟ GroupDocs.Signature for Java (الإصدار 23.12 أو أحدث).
- هل أحتاج إلى ترخيص؟ نسخة تجريبية مجانية تكفي للاختبار؛ الترخيص الكامل مطلوب للإنتاج.
- هل يمكن استبدال XOR بـ AES لاحقاً؟ نعم — استبدل منطق
encrypt/decryptمع الحفاظ على واجهةIDataEncryptionنفسها.
ما هو التشفير المخصص في Java؟
IDataEncryption هي واجهة في GroupDocs.Signature تُعرّف طرق تشفير وفك تشفير البيانات. يتيح لك التشفير المخصص تحديد كيفية تحويل البيانات قبل تخزينها أو نقلها. مع GroupDocs.Signature، تزود المكتبة بتنفيذك لواجهة IDataEncryption، وستستدعي شفرتك تلقائياً كلما احتاجت لحماية بيانات التوقيع. هذا النموذج القابل للإضافة يعني أنه يمكنك البدء بروتين XOR بسيط لإثبات المفهوم ثم استبداله لاحقاً بـ AES‑256 دون تعديل باقي سير عمل التوقيع.
لماذا التشفير المخصص مهم
التشفير المخصص يكون ذا قيمة عندما لا تستطيع الخوارزميات الموجودة تلبية قيود محددة مثل صيغ بروتوكولات قديمة، ميزانيات أداء صارمة، أو متطلبات عقود ملكية. من خلال تنفيذ روتينك الخاص تحتفظ بالتحكم الكامل في تحويل البيانات، تقلل الحمل، وتضمن التوافق دون إعادة كتابة الأنظمة الخارجية، مع الاستفادة من قابلية توسيع GroupDocs.
تكامل الأنظمة القديمة
في بعض الأنظمة القديمة يلزم تحويل بايت‑بايت محدد — غالباً XOR بمفتاح بايت واحد. إعادة هندسة تلك الأنظمة مكلفة، لذا مطابقة توقعاتهم بمشفّر مخصص هو المسار العملي.
تحسين الأداء
الخوارزميات القياسية مثل AES‑256 قوية تشفرياً لكن قد تستهلك دورات CPU ملحوظة، خاصة على الأجهزة منخفضة الطاقة أو عند معالجة ملايين الحمولة الصغيرة. XOR يُنفّذ بتعليمات CPU واحدة لكل بايت، مما يوفّر تقريباً صفر تكلفة للبيانات غير الحساسة.
المتطلبات الملكية
بعض العقود أو المعايير الصناعية تفرض خوارزمية مخصصة (مثلاً “قناع XOR” حكومي). تنفيذ المنطق المطلوب بنفسك يضمن الامتثال مع الحفاظ على بقية البنية الحديثة.
التعلم والمرونة
بناء مشفر مخصص يجبرك على فهم عمليات البايت، إدارة المفاتيح، وتصميم الواجهة IDataEncryption المدفوع بالعقود. هذه المعرفة تُستَفاد عندما تتبنى تشفيراً أكثر تعقيداً لاحقاً.
نصيحة محترف: استخدم التشفير المخصص فقط للبيانات التي تحميها طبقات أخرى (TLS، VPN، أو تشفير قاعدة البيانات). لا تعتمد على XOR كخط دفاع وحيد للمعلومات الشخصية أو المالية.
فهم XOR: الأساسيات
XOR (exclusive OR) يقارن بتين ويعيد 1 إذا كانا مختلفين، 0 إذا كانا متطابقين:
- 0 XOR 0 = 0
- 0 XOR 1 = 1
- 1 XOR 0 = 1
- 1 XOR 1 = 0
نظرًا لأن العملية هي عكس نفسها، تطبيق المفتاح نفسه مرة ثانية يعيد القيمة الأصلية. في Java يمكنك XOR بايتين باستخدام عامل ^:
byte encrypted = (byte)(plainByte ^ key);
عند XOR مصفوفة بايت كاملة بمفتاح بايت واحد، تحصل على تحويل سريع وقابل للعكس. تذكر أن مفتاح بايت واحد يوفّر فقط 255 احتمالاً، لذا يمكن لأي شخص يمتلك كمية قليلة من النص المشفر كسر المفتاح فوراً. استخدمه فقط للإخفاء، وليس لحماية البيانات السرية.
المتطلبات المسبقة
قبل تنفيذ تشفير مخصص مع GroupDocs.Signature for Java، تأكد من توفر ما يلي:
المكتبات والاعتمادات المطلوبة
- GroupDocs.Signature for Java – الإصدار 23.12 أو أحدث (API الذي سنستخدمه طوال الدليل).
- Java Development Kit – JDK 8 أو أحدث؛ يُفضَّل JDK 11 للدعم طويل الأمد.
متطلبات إعداد البيئة
- بيئة تطوير متكاملة مثل IntelliJ IDEA، Eclipse، أو VS Code مع ملحقات Java.
- Maven أو Gradle لإدارة الاعتمادات (كلاهما مدعومان).
المتطلبات المعرفية
- إلمام بفئات Java، الواجهات، ومعالجة مصفوفات البايت.
- فهم أساسي لمفاهيم التشفير المتماثل (مغطى في قسم XOR).
إذا تحققت من جميع النقاط، فأنت جاهز لإضافة GroupDocs إلى مشروعك.
إعداد GroupDocs.Signature لـ Java
إدخال المكتبة إلى نظام البناء هو سطر واحد من XML أو Groovy.
Maven
<dependency>
<groupId>com.groupdocs</groupId>
<artifactId>groupdocs-signature</artifactId>
<version>23.12</version>
</dependency>
Gradle
implementation 'com.groupdocs:groupdocs-signature:23.12'
التحميل المباشر
إذا كنت تفضّل الإدارة اليدوية، احصل على الـ JAR من GroupDocs.Signature for Java releases وأضفه إلى مسار الـ classpath.
خطوات الحصول على الترخيص
- Free Trial – حمّل JAR التجريبي؛ الملفات الناتجة تحتوي على علامة مائية مرئية.
- Temporary License – اطلب مفتاح تقييم لمدة 30 يوماً لاختبار كامل المميزات.
- Purchase – احصل على ترخيص دائم للنشر في بيئات الإنتاج.
التهيئة الأساسية والإعداد
Signature signature = new Signature("sample.pdf");
كائن Signature هو نقطة الدخول لجميع عمليات التوقيع، التحقق، والتشفير في GroupDocs.Signature.
دليل التنفيذ
ميزة تشفير XOR مخصص
سننشئ فئة تُنفّذ واجهة IDataEncryption، ثم نسجّها مع كائن Signature.
الخطوة 1: تنفيذ واجهة IDataEncryption
IDataEncryption هي واجهة GroupDocs.Signature التي تُعرّف طرق تشفير وفك تشفير البيانات.
public class CustomXOREncryption implements IDataEncryption {
private byte auto_Key = 0x5A; // example key
@Override
public byte[] encrypt(byte[] data) { /* implementation below */ }
@Override
public byte[] decrypt(byte[] data) { /* implementation below */ }
public void setKey(byte key) { this.auto_Key = key; }
public byte getKey() { return this.auto_Key; }
}
ما يحدث: الفئة تعد بتنفيذ عمليتين أساسيتين — encrypt و decrypt. الحقل auto_Key يخزن مفتاح XOR الذي سيُطبّق على كل بايت من الحمولة.
الخطوة 2: تعريف طرق التشفير وفك التشفير
نظرًا لأن XOR متماثل، كلا الطريقتين تنفّذان نفس التحويل البايت‑بايت.
public byte[] encrypt(byte[] data) {
if (auto_Key == 0 || data == null) return data;
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++) {
result[i] = (byte)(data[i] ^ auto_Key);
}
return result;
}
public byte[] decrypt(byte[] data) {
return encrypt(data); // XOR decryption is identical to encryption
}
التفسير:
- عبارات الحماية تمنع المفتاح صفر (الذي لا يُغيّر شيئًا) والمدخلات
null. - يتم إنشاء مصفوفة بايت جديدة لتخزين البيانات المحوّلة لتجنب تعديل البuffer الأصلي.
- الحلقة تقوم بعملية XOR لكل بايت مع
auto_Key. - فك التشفير ببساطة يستدعي
encryptمرة أخرى، لأن تطبيق XOR نفسه مرتين يعيد البايتات الأصلية.
خيارات تكوين المفتاح
- auto_Key يجب أن تكون قيمة غير صفرية بين 1 و 255. القيم فوق 255 تُقص إلى الـ 8 بتات الأدنى.
- احفظ المفتاح بأمان — المتغيّرات البيئية، ملفات الإعداد المشفّرة، أو مدير أسرار مخصص هي الخيارات المفضلة.
- في بيئات الإنتاج قد تستبدل هذا البايت البسيط بمفتاح متعدد البايتات أو خوارزمية AES كاملة، لكن الواجهة تبقى كما هي.
مثال على ضبط المفتاح
CustomXOREncryption xor = new CustomXOREncryption();
xor.setKey((byte)0x3C); // set a custom key at runtime
signature.setDataEncryption(xor);
أخطاء التنفيذ الشائعة
| الخطأ | لماذا يضر | كيفية الإصلاح |
|---|---|---|
| نسيان ضبط المفتاح | يصبح التشفير بلا تأثير، وتبقى البيانات نصًا صريحًا. | احرص على استدعاء setKey() قبل استخدام المشفر، أو قدم مفتاحًا غير صفر افتراضيًا في المُنشئ. |
تجاهل البيانات null | يؤدي إلى NullPointerException أثناء التوقيع. | أضف if (data == null) return data; في بداية كلتا الطريقتين. |
| الافتراض أن XOR آمن | يمكن كسر مفتاح بايت واحد في مليثانية. | استخدم XOR فقط للإخفاء؛ استبدله بـ AES‑256 لأي حمولة سرية. |
| اختلاف المفاتيح عند فك التشفير | تصبح البيانات غير قابلة للاسترجاع. | احفظ المفتاح مع الحمولة المشفّرة أو استخدم خريطة معرف‑مفتاح. |
اعتبارات الأمان
لماذا XOR غير كافٍ للبيانات الحساسة
XOR بمفتاح بايت واحد لا يوفر قوة تشفيرية تقريبًا؛ يمكن للمهاجم تجربة جميع المفاتيح الـ 255 فورًا. العملية تُظهر أنماطًا إحصائية، ما يجعل هجمات التردد والهجمات المعروفة للنص واضحًا. لذلك لا ينبغي أن يكون XOR هو الحماية الوحيدة للمعلومات الشخصية أو المالية.
متى يكون XOR مقبولاً
يمكن استخدام XOR بأمان عندما تكون البيانات محمية بالفعل بطبقات أقوى مثل TLS، VPN، أو تشفير قاعدة البيانات، ويكون القناع مجرد مانع بسيط للعين أو لتلبية صيغة قديمة. يناسب المعرفات المؤقتة، مفاتيح التخزين المؤقت، أو العلامات الداخلية التي لا تغادر البيئة الموثوقة.
البدائل القوية الموصى بها
- AES‑256 – معيار الصناعة، مدعوم أصلاً عبر
javax.crypto. - RSA‑2048 – مفيد لتشفير مفاتيح متماثلة صغيرة.
- ChaCha20 – أداء عالي على معالجات الهواتف المحمولة.
نظرًا لأن عقد IDataEncryption لا يعتمد على الخوارزمية، فإن الانتقال إلى AES يتطلب فقط استبدال جسم encrypt/decrypt باستدعاءات الشيفرة المناسبة.
التطبيقات العملية
1. سير عمل توقيع المستند الآمن
قد تحتاج إلى تخزين بيانات تعريف الموقّع (المعرّف، الطابع الزمني، القسم) بطريقة تمنع الفحص العادي. باستخدام مشفر XOR الخاص بنا، تُخزن البيانات كـ byte array داخل حزمة التوقيع، بينما يبقى باقي PDF دون تعديل.
Signature signature = new Signature("contract.pdf");
signature.setDataEncryption(new CustomXOREncryption());
SignatureResult result = signature.sign("output.pdf", options);
2. فحص تكامل خفيف الوزن
قم بتشفير ثابت معروف واحتفظ به مع المستند. لاحقًا، فك التشفير وقارن للتحقق من عدم تلف الملف أثناء النقل.
3. جسر النظام القديم
نظام mainframe قديم يتوقع حمولة يُقنّع كل بايت فيها بـ 0x7F. بضبط المفتاح نفسه في CustomXOREncryption، يمكنك تبادل البيانات دون كتابة خدمة تحويل منفصلة.
اعتبارات الأداء
السرعة الخام
XOR يعمل تقريبًا 1 ns لكل بايت على نواة x86 حديثة، ما يعني أن حمولة 10 MB تُشفّر في أقل من 10 ms. بالمقابل، AES‑256 في وضع CBC يستغرق عادةً 3‑4 مرات أطول لنفس الحجم.
بصمة الذاكرة
تنفيذنا يخلق نسخة من المصفوفة المدخلة، مما يضاعف استهلاك الذاكرة مؤقتًا. لملف حجمه 50 MB ستحتاج إلى حوالي 100 MB من الـ heap أثناء التشفير. إذا كان عليك معالجة ملفات أكبر، عالج التدفق على قطع بحجم 4 KB:
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(target);
byte[] buffer = new byte[4096];
int read;
while ((read = in.read(buffer)) != -1) {
for (int i = 0; i < read; i++) {
buffer[i] ^= key;
}
out.write(buffer, 0, read);
}
أفضل الممارسات لإدارة الذاكرة في Java
- امسح المفتاح بعد الاستخدام:
Arrays.fill(keyArray, (byte)0); - استخدم try‑with‑resources لضمان إغلاق التدفقات.
- تجنّب تحويل البايتات المشفّرة إلى
String؛ احتفظ بها كـbyte[]صافية. - راقب الـ heap بأدوات مثل VisualVM عند معالجة مستندات كبيرة متعددة في وقت واحد.
استكشاف الأخطاء الشائعة
المشكلة 1 – “البيانات المفكوكة تبدو عشوائية”
الإجابة المباشرة: تأكد من استخدام نفس مفتاح XOR للتشفير وفك التشفير، احتفظ بالبيانات كمصفوفة بايت طوال السلسلة، وتجنّب أي تحويلات ترميزية قد تُفسد البايتات.
سبب حدوثها: مفتاح غير متطابق، تقصير البيانات، أو تحويل غير مقصود إلى String يغيّر نمط البايتات، مما يجعل الناتج غير قابل للقراءة.
المشكلة 2 – “NullPointerException أثناء التشفير”
الإجابة المباشرة: طريقة encrypt تتحقق من المدخلات null؛ إذا استمرت الاستثناءات، تحقق من أن مصفوفة البايت المصدر مهيأة بشكل صحيح قبل تمريرها إلى المشفر.
الإصلاح: أضف فحوصات دفاعية في الكود المستدعي أو تأكد من تحميل بيانات التوقيع عبر signature.getSignatureData() قبل التشفير.
المشكلة 3 – “التشفير يبدو غير فعال”
الإجابة المباشرة: غالبًا ما يعني ذلك أن مفتاح XOR مضبوط على 0. XOR مع الصفر لا يغيّر البايت الأصلي، لذا يكون الناتج مطابقًا للمدخل.
الحل: اضبط مفتاحًا غير صفر عبر setKey() أو قدم قيمة افتراضية غير صفر في المُنشئ.
المشكلة 4 – “OutOfMemoryError عند معالجة ملفات PDF الكبيرة”
الإجابة المباشرة: تحميل ملف PDF كامل في الذاكرة قبل التشفير قد يتجاوز سعة الـ JVM. انتقل إلى نهج تدفق يمعالجة الملف على قطع، كما هو موضح في قسم الأداء.
نصيحة: زد الحد الأقصى للـ heap (-Xmx2g) كإجراء مؤقت فقط؛ أعد هيكلة الشيفرة لتعمل على معالجة مقطعية لضمان القابلية للتوسع.
الأسئلة المتكررة
س: كيف أختار مفتاح XOR مناسب؟
ج: أي عدد صحيح غير صفر بين 1 و 255 يفي بالغرض، لكن المفتاح نفسه لا يوفر أمانًا. للحماية الفعلية، استبدل XOR بـ AES‑256 واحتفظ بالمفتاح في مخزن أسرار آمن.
س: هل يمكن تغيير مفتاح XOR أثناء التشغيل؟
ج: نعم — استدعِ setKey() بقيمة جديدة. تذكّر أن البيانات المشفّرة بالمفتاح القديم يجب فك تشفيرها قبل التبديل، وإلا ستفقد القدرة على استرجاعها.
س: ما هي بعض البدائل لـ XOR؟
ج: للتعلم، جرّب تشفير سيزر أو Base64 (رغم أن Base64 مجرد ترميز). للإنتاج، استخدم AES‑256، RSA‑2048، أو ChaCha20 عبر حزمة javax.crypto.
س: كيف يتعامل GroupDocs.Signature مع الملفات الكبيرة مع التشفير؟
ج: المكتبة تُبث محتوى PDF عندما يكون ذلك ممكنًا، لكن تنفيذك لـ IDataEncryption يحدد كيفية معالجة البيانات. نفّذ تشفيرًا على أساس القطع لتجنب تحميل الملف بالكامل في الذاكرة.
س: هل يمكن دمج هذه الميزة في تطبيق ويب؟
ج: بالتأكيد. سجّل المشفر كـ Spring Bean، حقن خدمة Signature، واحفظ المفتاح في متغيّر بيئي أو مدير أسرار. احرص على معالجة كل طلب في خيط منفصل لتجنّب التنافس على الموارد.
كيف يعمل تشفير XOR في Java؟
في Java، يُنفّذ XOR عبر عامل ^ على قيم البايت. تُحمّل النص الصريح إلى مصفوفة بايت، تُكرر عبر كل عنصر وتطبق byte ^ key. لأن XOR هو عكس نفسه، تشغيل الروتين نفسه مرة أخرى بالمفتاح نفسه يعيد البايتات الأصلية، ما يجعل التشفير وفك التشفير متماثلين.
ما هي خطوات تنفيذ التشفير المخصص مع GroupDocs؟
لإضافة تشفير مخصص، أنشئ أولاً فئة تُنفّذ واجهة IDataEncryption، ثم اكتب طريقتي encrypt و decrypt باستخدام خوارزميةك. بعد ذلك، سجّل المثيل مع كائن Signature عبر setDataEncryption. من هذه النقطة فصاعدًا، ستستدعي GroupDocs منطقك كلما احتاجت لحماية بيانات التوقيع.
الخلاصة
لقد استعرضنا دورة كاملة حول how to encrypt java باستخدام روتين XOR مخصص، دمجه مع GroupDocs.Signature، وتوضيح الحالات التي يضيف فيها هذا النهج قيمة. تذكّر:
- استخدم XOR فقط للإخفاء، وليس لحماية البيانات الشخصية أو المالية.
- واجهة
IDataEncryptionتوفر نقطة تبديل نظيفة لخوارزميات أقوى لاحقًا. - إدارة المفتاح، التعامل مع الذاكرة، والبث هي عوامل أساسية لاستقرار الإنتاج.
الخطوات التالية:
- استبدل منطق XOR بـ AES‑256 للحصول على أمان حقيقي.
- نفّذ تدوير المفتاح وتخزينه بأمان.
- استكشف ميزات GroupDocs الأخرى مثل تدفقات التوقيع المتعددة، التحقق، وختم المستندات.
الآن لديك أساس قوي لتخصيص التشفير في أي حل توقيع Java — ابدأ بتكييفه وفق احتياجات عملك الدقيقة!
آخر تحديث: 2026-06-26
تم الاختبار مع: GroupDocs.Signature 23.12 for Java
المؤلف: GroupDocs
الموارد ذات الصلة:
- GroupDocs.Signature for Java Documentation
- API Reference
- Latest Release Download
- Purchase License
- Free Trial
- Temporary License Request
- GroupDocs Support Forum
Original data: 5 (binary: 0101)
Key: 3 (binary: 0011)
Encrypted: 5 XOR 3 = 6 (binary: 0110)
Decrypted: 6 XOR 3 = 5 (binary: 0101) ← We're back!
<dependency>
<groupId>com.groupdocs</groupId>
<artifactId>groupdocs-signature</artifactId>
<version>23.12</version>
</dependency>
implementation 'com.groupdocs:groupdocs-signature:23.12'
import com.groupdocs.signature.Signature;
class InitializeGroupDocs {
public static void main(String[] args) {
Signature signature = new Signature("path/to/your/document");
// Additional setup and operations can be performed here.
}
}
import com.groupdocs.signature.domain.extensions.encryption.IDataEncryption;
class CustomXOREncryption implements IDataEncryption {
private int auto_Key;
public final int getKey() {
return auto_Key;
}
// Additional methods for encryption and decryption will be implemented here.
}
class CustomXOREncryption {
private int auto_Key;
public byte[] encrypt(byte[] data) {
if (auto_Key == 0 || data == null) return data;
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++) {
result[i] = (byte) (data[i] ^ auto_Key);
}
return result;
}
public byte[] decrypt(byte[] encryptedData) {
// Since XOR is symmetric, use the same method as encryption
return encrypt(encryptedData);
}
}
CustomXOREncryption encryption = new CustomXOREncryption();
encryption.setKey(42); // Any non-zero value works
CustomXOREncryption encryption = new CustomXOREncryption();
// Oops! Never called setKey(), so auto_Key is 0
byte[] encrypted = encryption.encrypt(myData); // Returns data unchanged!
Signature signature = new Signature("contract.pdf");
CustomXOREncryption encryption = new CustomXOREncryption();
encryption.setKey(73); // Configure your key
// GroupDocs will use your encryption for signature data
// (Actual integration depends on specific GroupDocs API methods)
String integrityToken = "VALID_SIGNATURE_2025";
byte[] encrypted = encryption.encrypt(integrityToken.getBytes());
// Store encrypted with document...
// Later, decrypt and compare to verify nothing changed
// Old system expects data encrypted with XOR key 42
CustomXOREncryption legacyEncryption = new CustomXOREncryption();
legacyEncryption.setKey(42);
// Encrypt data before sending to legacy system
byte[] dataForOldSystem = legacyEncryption.encrypt(modernData);
sendToLegacyAPI(dataForOldSystem);
// More memory‑efficient for large data
public void encryptInPlace(byte[] data) {
if (auto_Key == 0 || data == null) return;
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (data[i] ^ auto_Key);
}
}
Arrays.fill(decryptedData, (byte) 0); // Overwrite with zeros
try (FileInputStream fis = new FileInputStream("encrypted.dat")) {
// Process data
} // Automatically closed
assert auto_Key != 0 : "Encryption key must be set!";
try (FileInputStream in = new FileInputStream(path);
FileOutputStream out = new FileOutputStream(encryptedPath)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
encryptInPlace(buffer, 0, bytesRead);
out.write(buffer, 0, bytesRead);
}
}
@Component
public class EncryptionService {
private CustomXOREncryption encryption;
public EncryptionService(@Value("${app.encryption.key}") int key) {
this.encryption = new CustomXOREncryption();
this.encryption.setKey(key);
}
// Use in your controllers...
}