0

I want to encode my payload data for a form so that on submission the view function for my registration decodes the data and performs necessary validation on the data and saves it to the database. However, I keep getting the error below.

Error at /register/
Incorrect padding

Here is the complete Traceback

Environment:


Request Method: POST
Request URL: http://localhost:8003/register/

Django Version: 4.2
Python Version: 3.9.12
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'authentication',
 'rest_framework',
 'rest_framework_simplejwt.token_blacklist',
 'corsheaders']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
    return view_func(*args, **kwargs)
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/dubsy/virtualenvs/djangoproject/digirepo2/authentication/views.py", line 86, in post
    cipher = AES.new(base64.b64decode(encryption_secret_key), AES.MODE_ECB)
  File "/home/dubsy/anaconda3/lib/python3.9/base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)

Exception Type: Error at /register/
Exception Value: Incorrect padding

Below are the code snippet that handles the submission of the form data, encryption and decryption in front and back end respectively

import React, { useState } from "react";
import axios from "axios";
import CryptoJS from "crypto-js";

function Signup() {
  const [focusedInput, setFocusedInput] = useState("");
  const [formData, setFormData] = useState({
    email: "",
    first_name: "",
    last_name: "",
    password: "",
    password2: "",
  });
  const handleChange = (e) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value,
    });
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const encryptionSecretKey = "t42uM-crGNqn9tugFvY0IkV6tdKk4RbWbREflNaZ8QA=";


    const encryptedPassword = CryptoJS.AES.encrypt(
      formData.password,
      encryptionSecretKey
    ).toString();

    const encryptedPassword2 = CryptoJS.AES.encrypt(
      formData.password2,
      encryptionSecretKey
    ).toString();

    const encryptedEmail = CryptoJS.AES.encrypt(
      formData.email,
      encryptionSecretKey
    ).toString();

    const encryptedPayload = {
      ...formData,
      password: encryptedPassword,
      password2: encryptedPassword2,
      email: encryptedEmail,
    };

    // Send the encrypted payload to the backend
    axios
      .post("http://127.0.0.1:8003/register/", JSON.stringify(encryptedPayload))
      .then((response) => {
        // Handle successful response
        console.log(response.data);
      })
      .catch((error) => {
        // Handle error
        console.error(error);
      });
  };
class CreateUser(APIView):
    permission_classes = [AllowAny]

    
    def post(self, request):
        encrypted_payload = request.data.get('encryptedPayload')
        encryption_secret_key = "t42uM-crGNqn9tugFvY0IkV6tdKk4RbWbREflNaZ8QA="
        cipher = AES.new(base64.b64decode(encryption_secret_key), AES.MODE_ECB)
        decrypted_payload = cipher.decrypt(
            base64.b64decode(encrypted_payload)).decode().rstrip('\0')
        decrypted_data = json.loads(decrypted_payload)
        serializer = UserSerializer(data=decrypted_data)

        if serializer.is_valid(raise_exception=True):
            user = serializer.save()
            # Modify the user attributes as needed
            user.email = user.email.lower()
            user.username = user.email.lower() if user.email else None
            user.first_name = user.first_name.lower() if user.first_name else None
            user.last_name = user.last_name.lower() if user.last_name else None
            user.avatar = user.avatar if user.avatar else None
            if user.first_name and user.last_name:
                random_string = generate_random_string()
                slug = slugify(
                    f"{user.first_name} {user.last_name} {random_string}")
                while User.objects.filter(slug=slug).exists():
                    random_string = generate_random_string()
                    slug = slugify(
                        f"{user.first_name} {user.last_name} {random_string}"
                    )
                user.slug = slug

            user.set_password(decrypted_data["password"])
            user.password2 = None
            user.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

How do i solve the issue i am having.

Olasubomi
  • 157
  • 1
  • 10

1 Answers1

0

You just need to add more padding to get a valid input for base64 decode. There is a great answer that explains that you can simply add always two == at the end of the input which is the maximum padding that you ever need. base64.decode removes automatically unnecessary padding at the end.

So, t42uM-crGNqn9tugFvY0IkV6tdKk4RbWbREflNaZ8QA== will work as well as t42uM-crGNqn9tugFvY0IkV6tdKk4RbWbREflNaZ8QA========= as explained above.

Marco
  • 2,371
  • 2
  • 12
  • 19
  • my encryption secret key has one `=` at the end of the input and when i add two or more `=` sign, i get the error **Incorrect AES key length (31 bytes)**. How do i fix it – Olasubomi Jul 15 '23 at 17:59