চূড়ান্ত ব্লকটি সঠিকভাবে প্যাড করা হয়নি


115

আমি পাসওয়ার্ড ভিত্তিক এনক্রিপশন অ্যালগরিদম বাস্তবায়নের চেষ্টা করছি, তবে আমি এই ব্যতিক্রমটি পেয়েছি:

javax.crypto.BadPaddingException: প্রদত্ত চূড়ান্ত ব্লকটি সঠিকভাবে প্যাড করা হয়নি

সমস্যাটা কি হতে পারে?

আমার কোডটি এখানে:

public class PasswordCrypter {

    private Key key;

    public PasswordCrypter(String password)  {
        try{
            KeyGenerator generator;
            generator = KeyGenerator.getInstance("DES");
            SecureRandom sec = new SecureRandom(password.getBytes());
            generator.init(sec);
            key = generator.generateKey();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public byte[] encrypt(byte[] array) throws CrypterException {
        try{
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            return cipher.doFinal(array);
        } catch (Exception e) { 
            e.printStackTrace();
        }
        return null;
    }

    public byte[] decrypt(byte[] array) throws CrypterException{
        try{
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);

            return cipher.doFinal(array);
        } catch(Exception e ){
            e.printStackTrace();
        }
        return null;
    }
}

(জাবিট পরীক্ষা)

public class PasswordCrypterTest {

    private static final byte[] MESSAGE = "Alpacas are awesome!".getBytes();
    private PasswordCrypter[] passwordCrypters;
    private byte[][] encryptedMessages;

    @Before
    public void setUp() {
        passwordCrypters = new PasswordCrypter[] {
            new PasswordCrypter("passwd"),
            new PasswordCrypter("passwd"),
            new PasswordCrypter("otherPasswd")
        };

        encryptedMessages = new byte[passwordCrypters.length][];
        for (int i = 0; i < passwordCrypters.length; i++) {
            encryptedMessages[i] = passwordCrypters[i].encrypt(MESSAGE);
        }
    }

    @Test
    public void testEncrypt() {
        for (byte[] encryptedMessage : encryptedMessages) {
            assertFalse(Arrays.equals(MESSAGE, encryptedMessage));
        }

        assertFalse(Arrays.equals(encryptedMessages[0], encryptedMessages[2]));
        assertFalse(Arrays.equals(encryptedMessages[1], encryptedMessages[2]));
    }

    @Test
    public void testDecrypt() {
        for (int i = 0; i < passwordCrypters.length; i++) {
            assertArrayEquals(MESSAGE, passwordCrypters[i].decrypt(encryptedMessages[i]));
        }

        assertArrayEquals(MESSAGE, passwordCrypters[0].decrypt(encryptedMessages[1]));
        assertArrayEquals(MESSAGE, passwordCrypters[1].decrypt(encryptedMessages[0]));

        try {
            assertFalse(Arrays.equals(MESSAGE, passwordCrypters[0].decrypt(encryptedMessages[2])));
        } catch (CrypterException e) {
            // Anything goes as long as the above statement is not true.
        }

        try {
            assertFalse(Arrays.equals(MESSAGE, passwordCrypters[2].decrypt(encryptedMessages[1])));
        } catch (CrypterException e) {
            // Anything goes as long as the above statement is not true.
        }
    }
}

উত্তর:


197

আপনি যদি ভুল কী দিয়ে পিকেসিএস 5-প্যাডযুক্ত ডেটা ডিক্রিপ্ট করার চেষ্টা করেন, এবং তারপরে এটি আনপড করুন (যা স্বয়ংক্রিয়ভাবে সিফার শ্রেণি দ্বারা সম্পন্ন করা হয়), আপনি সম্ভবত ব্যাডপ্যাডিংএক্সেপশন পাবেন (সম্ভবত 255/256 এর চেয়ে কিছুটা কম, প্রায় 99.61% ), কারণ প্যাডিংয়ের একটি বিশেষ কাঠামো রয়েছে যা আনপ্যাড চলাকালীন যাচাই করা হয় এবং খুব কম কীগুলি বৈধ প্যাডিং উত্পাদন করতে পারে।

সুতরাং, আপনি যদি এই ব্যতিক্রমটি পান তবে এটি ধরুন এবং এটিকে "ভুল কী" হিসাবে বিবেচনা করুন।

আপনি যখন কোনও ভুল পাসওয়ার্ড সরবরাহ করেন তখন এটিও ঘটতে পারে যা কীস্টোর থেকে কীটি পেতে ব্যবহৃত হয় বা কী প্রজন্মের ফাংশনটি ব্যবহার করে কীতে রূপান্তরিত হয়।

অবশ্যই, আপনার ডেটা পরিবহণে দূষিত হলে খারাপ প্যাডিংও ঘটতে পারে।

এটি বলেছিল, আপনার স্কিম সম্পর্কে কিছু সুরক্ষা মন্তব্য রয়েছে:

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

  • ইসিবি-মোড ব্যবহার করবেন না। এটি প্রতিটি ব্লককে স্বতন্ত্রভাবে এনক্রিপ্ট করে, যার অর্থ অভিন্ন প্লেইন ব্লকগুলি সর্বদা অভিন্ন সিফেরেক্সট ব্লক দেয়।

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

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

  • DES এর কার্যকর কী আকার কেবল 56 বিট। এই মূল স্থানটি বেশ ছোট, এটি কোনও ডেডিকেটেড আক্রমণকারী দ্বারা কয়েক ঘন্টার মধ্যে নৃশংস হতে পারে। আপনি যদি কোনও পাসওয়ার্ড দ্বারা আপনার কী তৈরি করেন তবে এটি আরও দ্রুত get এছাড়াও, ডিইএসের কেবলমাত্র 64 বিটের একটি ব্লক আকার রয়েছে, যা শৃঙ্খলিত মোডগুলিতে আরও কিছু দুর্বলতা যুক্ত করে। পরিবর্তে AES এর মতো একটি আধুনিক অ্যালগরিদম ব্যবহার করুন, যার ব্লক আকার 128 বিট এবং 128 বিটের একটি মূল আকার (স্ট্যান্ডার্ড বৈকল্পিকের জন্য)।


1
আমি শুধু নিশ্চিত করতে চাই আমি এনক্রিপশনে নতুন এবং এটি আমার দৃশ্য, আমি এসইএস এনক্রিপশন ব্যবহার করছি। আমার এনক্রিপ্ট / ডিক্রিপ্ট ফাংশনে, আমি একটি এনক্রিপশন কী ব্যবহার করছি। ডিক্রিপ্টে আমি একটি ভুল এনক্রিপশন কী ব্যবহার করেছি এবং আমি এটি পেয়েছি javax.crypto.BadPaddingException: Given final block not properly padded। আমি কি এটি একটি ভুল কী হিসাবে বিবেচনা করব?
কেনিকি

কেবল পরিষ্কার বলতে গেলে, কী স্টোর ফাইলের জন্য, যেমন একটি .p12 ফাইলের জন্য ভুল পাসওয়ার্ড সরবরাহ করার সময় এটি ঘটতে পারে যা আমার কাছে ঘটেছিল is
ওয়ারেন ডিউ

2
@ ওয়ারেনডিউ "একটি মূল স্টোরের ফাইলের জন্য ভুল পাসওয়ার্ড" "ভুল কী" এর একটি বিশেষ কেস।
পাওলো ইবারম্যান

@ কনিকি দুঃখিত, আমি এখনই আপনার মন্তব্যটি দেখেছি ... হ্যাঁ, একটি ভুল কী প্রায়শই এই প্রভাবের কারণ হয়। (অবশ্যই, দুর্নীতিগ্রস্থ ডেটা অন্য সম্ভাবনা))
প্যালো ইবারম্যান

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

1

আপনি যে ক্রিপ্টোগ্রাফি অ্যালগরিদম ব্যবহার করছেন তার উপর নির্ভর করে আপনাকে বাইট অ্যারের এনক্রিপ্ট করার আগে শেষে কিছু প্যাডিং বাইট যুক্ত করতে হতে পারে যাতে বাইট অ্যারের দৈর্ঘ্য ব্লকের আকারের একাধিক হয়:

বিশেষ করে আপনার ক্ষেত্রে প্যাডিং স্কিমা আপনি বেছে PKCS5 যা এখানে বর্ণিত হয়: http://www.rsa.com/products/bsafe/documentation/cryptoj35html/doc/dev_guide/group_ সিজে _SYM__PAD.html

(আমি ধরে নিয়েছি আপনি এনক্রিপ্ট করার চেষ্টা করার সময় আপনার সমস্যা আছে)

আপনি যখন সাইফার অবজেক্টটি ইনস্ট্যান্ট করবেন তখন আপনি আপনার প্যাডিং স্কিমা চয়ন করতে পারেন। সমর্থিত মানগুলি আপনি যে সুরক্ষা সরবরাহকারীর ব্যবহার করছেন তার উপর নির্ভর করে।

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


1
সুতরাং আপনি দয়া করে কোড পোস্ট করতে পারেন যা এনক্রিপ্ট / ডিক্রিপ্ট করার চেষ্টা করে? (এবং পরীক্ষা করুন যে বাইট অ্যারে আপনি ডিক্রিপ্ট করার চেষ্টা করছেন তা ব্লকের আকারের চেয়ে বড় নয়)
fpacifici

1
আমি জাভা এবং ক্রিপ্টোগ্রাফিতে খুব নতুন তাই আমি এখনও এনক্রিপশন করার আরও ভাল উপায় জানি না। আমি সম্ভবত এটি বাস্তবায়নের আরও ভাল উপায়গুলির চেয়ে তার এটি সম্পন্ন করতে চাই।
আল্ট্রিমে

আপনি কি লিঙ্কটি আপডেট করতে পারবেন কারণ এটি @fpacifici কাজ করে না এবং আমি আমার পোস্ট আপডেট করেছি আমি JUnit পরীক্ষা অন্তর্ভুক্ত করেছি যা এনক্রিপশন এবং ডিক্রিপশন পরীক্ষা করে
Altrim

সংশোধন করা হয়েছে (দুঃখিত কপির পেস্ট ত্রুটি)। যাইহোক, প্রকৃতপক্ষে আপনার সমস্যাটি ঘটেছিল যেহেতু আপনি কোনও কী দিয়ে ডিক্রিপ্ট করেছেন যা এনক্রিপশনের জন্য ব্যবহৃত একটির মতো নয় যা পাওলো ব্যাখ্যা করেছেন। জুনিটে @ পূর্বের সাথে বর্ণিত পদ্ধতিটি প্রতিটি পরীক্ষার পদ্ধতির আগেই কার্যকর করা হয়, সুতরাং প্রতিবার কীটি পুনরায় তৈরি করা হয়। যেহেতু চাবিটি এলোমেলোভাবে শুরু করা হয়েছে এটি প্রতিবারই আলাদা হবে।
fpacifici

1

অপারেশন সিস্টেমের কারণে আমি এই সমস্যাটি পূরণ করেছি, জেআরই বাস্তবায়ন সম্পর্কে বিভিন্ন প্ল্যাটফর্ম simple

new SecureRandom(key.getBytes())

উইন্ডোতে একই মান পাবে, যখন এটি লিনাক্সে আলাদা। সুতরাং লিনাক্স এ পরিবর্তন করা প্রয়োজন

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key.getBytes());
kgen.init(128, secureRandom);

"SHA1PRNG" হল ব্যবহৃত অ্যালগরিদম, আপনি অ্যালগরিদম সম্পর্কে আরও তথ্যের জন্য এখানে উল্লেখ করতে পারেন ।


0

আপনি যখন নিজের সাইন কীটির জন্য ভুল পাসওয়ার্ড প্রবেশ করেন এটিও সমস্যা হতে পারে।


এটি আসলে একটি মন্তব্য, উত্তর নয়। আরও কিছুটা প্রতিনিধির সাথে আপনি মন্তব্য পোস্ট করতে সক্ষম হবেন
অ্যাড্রিয়ান মোল

এটি কোনও উত্তর নয়
জিগ রেজার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.