কনফিগারেশন ফাইলগুলিতে পাসওয়ার্ড এনক্রিপ্ট করবেন? [বন্ধ]


130

আমার একটি প্রোগ্রাম রয়েছে যা একটি কনফিগারেশন ফাইল থেকে সার্ভারের তথ্য পড়ে এবং সেই কনফিগারেশনে পাসওয়ার্ডটি এনক্রিপ্ট করতে চাই যা আমার প্রোগ্রাম দ্বারা পড়ে এবং ডিক্রিপ্ট করা যায়।

requirments:

  • ফাইলটিতে সঞ্চয় করতে প্লেটেক্সট পাসওয়ার্ড এনক্রিপ্ট করুন
  • আমার প্রোগ্রাম থেকে ফাইল থেকে পড়া এনক্রিপ্ট করা পাসওয়ার্ড ডিক্রিপ্ট করুন

আমি কীভাবে এটি করতে যাব তার কোনও পুনরুদ্ধার? আমি আমার নিজের অ্যালগরিদম লেখার কথা ভাবছিলাম তবে আমি মনে করি এটি মারাত্মকভাবে নিরাপত্তাহীন হবে।

উত্তর:


172

এটি করার একটি সহজ উপায় জাভায় পাসওয়ার্ড ভিত্তিক এনক্রিপশন ব্যবহার করা। এটি আপনাকে পাসওয়ার্ড ব্যবহার করে একটি পাঠ এনক্রিপ্ট এবং ডিক্রিপ্ট করতে দেয়।

এই মূলত একটি আরম্ভের মানে javax.crypto.Cipherআলগোরিদিম সঙ্গে "AES/CBC/PKCS5Padding"থেকে একটি কী পেয়ে javax.crypto.SecretKeyFactoryসঙ্গে "PBKDF2WithHmacSHA512"অ্যালগরিদম।

এখানে একটি কোড উদাহরণ রয়েছে (কম সুরক্ষিত MD5- ভিত্তিক বৈকল্পিক প্রতিস্থাপনের জন্য আপডেট করা হয়েছে):

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class ProtectedConfigFile {

    public static void main(String[] args) throws Exception {
        String password = System.getProperty("password");
        if (password == null) {
            throw new IllegalArgumentException("Run with -Dpassword=<password>");
        }

        // The salt (probably) can be stored along with the encrypted data
        byte[] salt = new String("12345678").getBytes();

        // Decreasing this speeds down startup time and can be useful during testing, but it also makes it easier for brute force attackers
        int iterationCount = 40000;
        // Other values give me java.security.InvalidKeyException: Illegal key size or default parameters
        int keyLength = 128;
        SecretKeySpec key = createSecretKey(password.toCharArray(),
                salt, iterationCount, keyLength);

        String originalPassword = "secret";
        System.out.println("Original password: " + originalPassword);
        String encryptedPassword = encrypt(originalPassword, key);
        System.out.println("Encrypted password: " + encryptedPassword);
        String decryptedPassword = decrypt(encryptedPassword, key);
        System.out.println("Decrypted password: " + decryptedPassword);
    }

    private static SecretKeySpec createSecretKey(char[] password, byte[] salt, int iterationCount, int keyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
        PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterationCount, keyLength);
        SecretKey keyTmp = keyFactory.generateSecret(keySpec);
        return new SecretKeySpec(keyTmp.getEncoded(), "AES");
    }

    private static String encrypt(String property, SecretKeySpec key) throws GeneralSecurityException, UnsupportedEncodingException {
        Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        pbeCipher.init(Cipher.ENCRYPT_MODE, key);
        AlgorithmParameters parameters = pbeCipher.getParameters();
        IvParameterSpec ivParameterSpec = parameters.getParameterSpec(IvParameterSpec.class);
        byte[] cryptoText = pbeCipher.doFinal(property.getBytes("UTF-8"));
        byte[] iv = ivParameterSpec.getIV();
        return base64Encode(iv) + ":" + base64Encode(cryptoText);
    }

    private static String base64Encode(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    private static String decrypt(String string, SecretKeySpec key) throws GeneralSecurityException, IOException {
        String iv = string.split(":")[0];
        String property = string.split(":")[1];
        Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        pbeCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(base64Decode(iv)));
        return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
    }

    private static byte[] base64Decode(String property) throws IOException {
        return Base64.getDecoder().decode(property);
    }
}

একটি সমস্যা রয়ে গেছে: পাসওয়ার্ডগুলি এনক্রিপ্ট করার জন্য আপনি যে পাসওয়ার্ডটি ব্যবহার করছেন তা কোথায় সংরক্ষণ করবেন? আপনি এটি উত্স ফাইলে সংরক্ষণ করতে পারেন এবং এটি বিস্মৃত করতে পারেন, তবে এটি আবার খুঁজে পাওয়া খুব কঠিন নয়। বিকল্পভাবে, আপনি জাভা প্রক্রিয়া ( -DpropertyProtectionPassword=...) শুরু করার সময় আপনি এটি একটি সিস্টেম সম্পত্তি হিসাবে দিতে পারেন ।

আপনি কীস্টোর ব্যবহার করেন তবে একই সমস্যাটি রয়ে গেছে যা একটি পাসওয়ার্ড দ্বারা সুরক্ষিত। মূলত, আপনার কোথাও একটি করে মাস্টার পাসওয়ার্ড থাকা দরকার এবং এটি রক্ষা করা বেশ শক্ত।


3
কোড উদাহরণের জন্য ধন্যবাদ, আমি এটি শেষ করে কীভাবে শেষ করেছি তা অনেকটাই। সেই একই পাসওয়ার্ডটিকে সুরক্ষিত করে যে পাসওয়ার্ডগুলিতে আমি একই সমস্যার মধ্যে পড়েছিলাম, আমি আপাতত এটি অবিস্মরণীয় পদ্ধতিটি সরিয়ে নিয়েছি তবে এখনও একটি গ্রহণযোগ্য সমাধান নিয়ে আসতে পারিনি, আপনার পরামর্শের জন্য ধন্যবাদ।
পিটি বি

7
"বিকল্পভাবে, আপনি যখন জাভা প্রক্রিয়া শুরু করেন তখন আপনি এটি একটি সিস্টেম সম্পত্তি হিসাবে দিতে পারেন (-প্রসারণপ্রেটিশনপ্যাসওয়ার্ড = ...)"। নোট করুন যে এটি (জিএনইউ / লিনাক্স) / ইউএনআইএক্স উপর "পিএস ফ্যাক্স" ব্যবহার করে পাসওয়ার্ডটি উত্তোলন করা সম্ভব করবে।
Ztyx

7
@ বেন আপনার পাঠ্য-ফাইল বা স্ট্রিং-ভিত্তিক ডাটাবেস কলামে বা অনুরূপ ফলস্বরূপ মান সংরক্ষণ করার জন্য বেস 64 এ এনকোড করা সাধারণ অভ্যাস।
আরবি।

4
@ ভি 7 নো এমডি 5 পাসওয়ার্ড হ্যাশিংয়ের জন্য একেবারেই সুরক্ষিত নয় এবং সে উদ্দেশ্যে কখনও ডিজাইন করা হয়নি। এটির জন্য কখনও এটি ব্যবহার করবেন না। আজকাল, আরগন 2 সেরা দেখুন owasp.org/index.php/Password_Storage_Cheat_Sheet এবং paragonie.com/blog/2016/02/how-safely-store-password-in-2016
Kimball রবিনসন

3
এইভাবে অনেক ভাল। অবশ্যই একটি নিরাপদ এলোমেলো লবণ এবং 40K এর একটি (রক্ষণশীল, নিম্ন প্রান্ত) এর একটি পুনরাবৃত্তি গণনাটি ভাল হবে তবে কমপক্ষে আপনি মন্তব্যগুলিতে এই বিষয়গুলি নির্দেশ করেছেন এবং পিবিকেডিএফ 2 এবং এইএস / সিবিসি সুনির্দিষ্ট উন্নতি। আমি উত্তরটি আপডেট করে আপনি কীভাবে এটি পরিচালনা করেছেন তা দুর্দান্ত বলে আমি মনে করি; আমি সতর্কতা অপসারণ করব। আপনার মন্তব্যটি ভোট দিয়েছেন যাতে আপডেট হওয়া কোডটি খুঁজে পেয়ে লোকেরা অবাক হয় না (তারা মনে করেন পুরানো কোডটি আবিষ্কার করার জন্য সম্পাদনাগুলি দেখতে পারেন)। আপনার পুরানো মন্তব্যগুলি সাফ করার জন্য একটি ভাল ধারণা হতে পারে।
মার্টেন বোদেউয়েস

20

হ্যাঁ, অবশ্যই আপনার নিজের অ্যালগরিদম লিখবেন না। জাভাতে প্রচুর ক্রিপ্টোগ্রাফি এপিআই রয়েছে।

আপনি যে ওএসটি ইনস্টল করছেন তাতে যদি কোনও কীস্টোর থাকে তবে আপনি এটি ব্যবহার করতে পারেন আপনার ক্রিপ্টো কীগুলি যা আপনার কনফিগারেশন বা অন্যান্য ফাইলগুলিতে সংবেদনশীল ডেটা এনক্রিপ্ট এবং ডিক্রিপ্ট করতে হবে।


4
একটি কীস্টোর ব্যবহারের জন্য +1! আপনি যদি জার ফাইলটিতে কীটি সংরক্ষণ করেন তবে তা অবজ্ঞা করা ছাড়া আর কিছুই নয়।
ninesided

2
যদি প্রয়োজনীয় সমস্ত কিছু পাসওয়ার্ডটি পরিষ্কার টেক্সটে সংরক্ষণ না করা হয় তবে কীস্টোরগুলি ওভারকিল হয়।
থরবজর্ন রাভন অ্যান্ডারসন 19

20

পরীক্ষা করে দেখুন jasypt , যা একটি গ্রন্থাগার সর্বনিম্ন প্রচেষ্টার সঙ্গে মৌলিক এনক্রিপশন ক্ষমতা প্রস্তাব।


16

আমি মনে করি যে সবচেয়ে ভালো উপায় তা নিশ্চিত করার জন্য আপনার কনফিগ ফাইল (আপনার পাসওয়ার্ড ধারণকারী) হয় শুধুমাত্র একটি নির্দিষ্ট ব্যবহারকারীর অ্যাকাউন্টের সাথে প্রবেশযোগ্য । উদাহরণস্বরূপ, আপনার কাছে একটি অ্যাপ্লিকেশন নির্দিষ্ট ব্যবহারকারী থাকতে appuserপারে যার কাছে কেবলমাত্র বিশ্বস্ত লোকদের পাসওয়ার্ড রয়েছে (এবং যার কাছে suতাদের রয়েছে)।

এইভাবে, কোনও বিরক্তিকর ক্রিপ্টোগ্রাফি ওভারহেড নেই এবং আপনার কাছে এখনও একটি পাসওয়ার্ড রয়েছে যা সুরক্ষিত।

সম্পাদনা: আমি ধরে নিচ্ছি যে আপনি আপনার অ্যাপ্লিকেশন কনফিগারেশনটি কোনও বিশ্বস্ত পরিবেশের বাইরে রফতানি করছেন না (যা আমি নিশ্চিত নই যে প্রশ্নটি দেওয়ার পরে কোনও অর্থ হবে)


4

মাস্টার পাসওয়ার্ডের সমস্যাগুলি সমাধান করার জন্য - সর্বোত্তম পন্থাটি কোথাও পাসওয়ার্ড সংরক্ষণ করা নয়, অ্যাপ্লিকেশনটিকে নিজের জন্য পাসওয়ার্ড এনক্রিপ্ট করতে হবে - যাতে এটি কেবল সেগুলি ডিক্রিপ্ট করতে পারে। সুতরাং আমি যদি একটি। কনফিগ ফাইল ব্যবহার করতাম তবে আমি নিম্নলিখিতটি করতাম , মাইসেটেটিংস কনফিগ :

encryptTheseKeys = secretKey, anotherSecret

secretKey = unprotectedPasswordThatIputHere

anotherSecret = anotherPass

someKey = unprotectedSettingIdontCareAbout

সুতরাং আমি এনক্রিপ্টসিসকিগুলিতে উল্লিখিত কীগুলিতে পড়তে পারি, উপরের থেকে ব্রডওয়ালসের উদাহরণটি প্রয়োগ করুন এবং কোনও ধরণের চিহ্নিতকারী ( ক্রিপট বলতে দিন:) অ্যাপ্লিকেশনটি যাতে এটি না করতে দেয় সে জন্য ফাইলটিতে তাদের আবার লিখুন ) আবার, আউটপুটটি দেখতে এই রকম হবে:

encryptTheseKeys = secretKey, anotherSecret

সিক্রেটকি = ক্রিপ্ট: ii4jfj304fjhfj934fouh938

আরেকটি সেক্রেট = ক্রিপ্ট: jd48jofh48h

someKey = unprotectedSettingIdontCareAbout

আপনার নিজের সুরক্ষিত জায়গায় মূলগুলি নিশ্চিত করে রাখুন ...


2
হ্যাঁ, এটি 3 বছর আগের। মাস্টার কী এড়াতে, আমি আমাদের অভ্যন্তরীণ সিএ থেকে জারি করা আরএসএ কী ব্যবহার করে শেষ করেছি প্রাইভেট কীটিতে অ্যাক্সেসটি মেশিন হার্ডওয়্যারটির আঙুলের মুদ্রণ সহ এনক্রিপ্ট করে সুরক্ষিত।
পিটি বি

আমি দেখতে পাচ্ছি, বেশ শক্ত লাগছে। সুন্দর।
ব্যবহারকারী 1007231

@ ব্যবহারকারী 1007231 - কোথায় রাখবেন - "কেবলমাত্র নিজের সুরক্ষিত জায়গায় মূলগুলি রাখবেন তা নিশ্চিত করুন ..."?
ন্যানোসফ্ট

@ পেটিবি - বুঝলেন না? আপনি কি আমাকে এমন কিছু লিঙ্কগুলিতে নির্দেশ করতে পারেন যা আমাকে আলোকিত করতে পারে। ধন্যবাদ
ন্যানোসফট

@ ন্যানোসফট - একটি "এজিস সিকিউর কী ইউএসবি" পান এবং সেখানে কোনও টেক্সট
ডকায়

4

সবচেয়ে বড় বিষয়, এবং রুমের হাতি এবং এটির সব কিছুই আপনার অ্যাপ্লিকেশনটি যদি পাসওয়ার্ডটি ধরে রাখতে পারে তবে বাক্সটিতে অ্যাক্সেস সহ একটি হ্যাকারও এটি ধরে রাখতে পারে!

এর চারপাশের একমাত্র উপায়, অ্যাপ্লিকেশনটি স্ট্যান্ডার্ড ইনপুট ব্যবহার করে কনসোলে "মাস্টার পাসওয়ার্ড" চেয়েছে এবং তারপরে এটি ফাইলটিতে সঞ্চিত পাসওয়ার্ডগুলি ডিক্রিপ্ট করার জন্য ব্যবহার করে। অবশ্যই, এটি সম্পূর্ণরূপে তৈরি করে যখন অ্যাপ্লিকেশনটি বুট হয় তখন অপ্রয়োজনীয় ওএসের সাথে শুরু করা অসম্ভব।

তবে, এই বিরক্তির এই স্তরের সাথেও, যদি কোনও হ্যাকার রুট অ্যাক্সেস পরিচালনা করতে সক্ষম হন (বা আপনার অ্যাপ্লিকেশনটি ব্যবহারকারী হিসাবে কেবল অ্যাক্সেস করতে পারে) তবে তিনি মেমরিটি ফেলে দিতে পারেন এবং পাসওয়ার্ডটি সেখানে খুঁজে পেতে পারেন find

নিশ্চিত করার বিষয়টি হ'ল, পুরো সংস্থাকে প্রোডাকশন সার্ভারে (এবং তারপরে পাসওয়ার্ডগুলিতে) অ্যাক্সেস না দেওয়া এবং নিশ্চিত করুন যে এই বাক্সটি ক্র্যাক করা অসম্ভব!


: বাস্তব সমাধান একটি কার্ড অথবা একটি HSM মত, অন্য কোথাও আপনার ব্যক্তিগত কী সঞ্চয় করতে হয় en.wikipedia.org/wiki/Hardware_security_module
atom88

1

ESAPIs এনক্রিপশন পদ্ধতি ব্যবহার করে দেখুন। এটি কনফিগার করা সহজ এবং আপনি সহজেই আপনার কীগুলি পরিবর্তন করতে পারেন।

http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/Encryptor.html

আপনি

1) এনক্রিপ্ট 2) ডিক্রিপ্ট 3) স্বাক্ষর 4) স্বাক্ষরিত 5) হ্যাশিং 6) সময় ভিত্তিক স্বাক্ষর এবং আরও একটি মাত্র লাইব্রেরি সহ।


1

কনফিগারেশন ফাইলগুলিতে পাসওয়ার্ড (বা হ্যাশ) সংরক্ষণের জন্য জেটিতে কী পাওয়া যায় তা দেখুন এবং বিবেচনা করুন যে ওবিএফ এনকোডিং আপনার পক্ষে কার্যকর হতে পারে কি না। তারপরে উত্সে দেখুন এটি কীভাবে সম্পন্ন হয়।

http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html


0

আপনার কনফিগারেশন ফাইলগুলি কতটা সুরক্ষিত বা আপনার অ্যাপ্লিকেশনটি কতটা নির্ভরযোগ্য তার উপর নির্ভর করে, http://activemq.apache.org/encrypted-passwords.html আপনার পক্ষে ভাল সমাধান হতে পারে।

আপনি যদি পাসওয়ার্ডটি ডিক্রিপ্ট হওয়ার ভয় পান না এবং পাসওয়ার্ড কী সংরক্ষণ করার জন্য বিনের সাহায্যে কনফিগার করা খুব সহজ হতে পারে। তবে আপনার যদি আরও সুরক্ষার প্রয়োজন হয় তবে আপনি গোপনীয়তার সাথে একটি পরিবেশের পরিবর্তনশীল সেট করতে এবং লঞ্চের পরে এটিকে সরাতে পারেন। এটির সাথে আপনাকে অ্যাপ্লিকেশন / সার্ভারটি ডাউন হয়ে যাওয়া এবং অ্যাপ্লিকেশনটি স্বয়ংক্রিয়ভাবে পুনরায় চালু না হওয়ার বিষয়ে চিন্তা করতে হবে।


: একটি HSM আদর্শ উপায় ব্যবহার করছে en.wikipedia.org/wiki/Hardware_security_module
atom88

-8

আপনি যদি জাভা 8 ব্যবহার করছেন তবে অভ্যন্তরীণ বেস 64 এনকোডার এবং ডিকোডার ব্যবহার করে প্রতিস্থাপন এড়ানো যায়

return new BASE64Encoder().encode(bytes);

সঙ্গে

return Base64.getEncoder().encodeToString(bytes);

এবং

return new BASE64Decoder().decodeBuffer(property);

সঙ্গে

return Base64.getDecoder().decode(property);

দ্রষ্টব্য যে এই সমাধানটি আপনার ডেটা সুরক্ষিত করে না কারণ ডিক্রিপটিংয়ের পদ্ধতিগুলি একই জায়গায় সংরক্ষণ করা হয়। এটি কেবল ভাঙ্গা আরও কঠিন করে তোলে। মূলত এটি মুদ্রণ করা এবং ভুল করে এটি সবার কাছে দেখাতে এড়ানো হয়।


26
বেস 64 এনক্রিপশন নয়।
jwilleke

1
বেস 64 এনক্রিপশন নয় এবং এটি আপনি প্রদান করতে পারেন এটি সবচেয়ে খারাপ উদাহরণ ... অনেক লোক বিশ্বাস করে যে বেস 64 একটি এনক্রিপশন অ্যালগরিটিম, তাই তাদের বিভ্রান্ত না করা আরও ভাল ...
রোবব

লক্ষ্য করুন যে উত্স ফাইলের শীর্ষে ডিকোড () পদ্ধতিটি প্রকৃত এনক্রিপশন করে। তবে এই বেস ফাংশনটি এটি ব্যবহার করতে পারে এমন কিছু (বাইট অ্যারে বাইট []] পাস করার জন্য একটি স্ট্রিং থেকে বাইটগুলি রূপান্তর করতে এই বেস 64 টি এনকোডিং এবং ডিকোডিংয়ের প্রয়োজন
atom88
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.