메인 콘텐츠로 건너뛰기

Crypt 파사드란

Laravel의 암호화 서비스는 OpenSSL의 AES-256-CBC 암호화(또는 AES-128-CBC)를 사용해 값의 암호화·복호화를 단순한 인터페이스로 제공합니다. Laravel에서 암호화된 모든 값은 **메시지 인증 코드(MAC)**로 서명되어 있습니다. 따라서 암호화 후의 값이 변조되면 복호화할 수 없게 됩니다.

설정

APP_KEY 생성

암호화를 사용하기 전에 config/app.phpkey 설정이 필요합니다. 이 값은 APP_KEY 환경 변수에서 읽어 들여집니다. php artisan key:generate 명령을 사용해 안전한 키를 생성해 주세요. PHP의 시큐어한 난수 생성기를 사용해 암호학적으로 안전한 키가 생성됩니다.
php artisan key:generate
Laravel 설치 시에는 일반적으로 자동 생성됩니다. 생성된 키는 .env 파일에 저장됩니다.
APP_KEY=base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY=
APP_KEY는 절대로 공개하지 마세요. 이 키가 유출되면 암호화된 데이터가 모두 복호화되어 버립니다.

암호화 키 로테이션

암호화 키를 변경하면 인증된 모든 사용자 세션이 로그아웃됩니다. Laravel은 세션 쿠키를 포함한 모든 쿠키를 암호화하고 있기 때문입니다. 또한 이전 키로 암호화된 데이터는 복호화할 수 없게 됩니다. 이 문제를 완화하기 위해 APP_PREVIOUS_KEYS에 오래된 키를 쉼표로 구분하여 나열할 수 있습니다.
APP_KEY="base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY="
APP_PREVIOUS_KEYS="base64:2nLsGFGzyoae2ax3EF2Lyq/hH6QghBGLIq5uL+Gp8/w="
Laravel은 암호화에는 항상 현재 키를 사용하지만, 복호화 시에는 현재 키로 실패한 경우에 오래된 키를 순서대로 시도합니다. 이를 통해 키 로테이션 중에도 사용자는 애플리케이션을 계속해서 사용할 수 있습니다.

암호화

Crypt 파사드의 encryptString 메서드를 사용해 값을 암호화합니다. 암호화된 값은 OpenSSL과 AES-256-CBC 암호를 사용하며, MAC으로 서명됩니다.
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;

class DigitalOceanTokenController extends Controller
{
    /**
     * 사용자의 API 토큰을 저장한다
     */
    public function store(Request $request): RedirectResponse
    {
        $request->user()->fill([
            'token' => Crypt::encryptString($request->token),
        ])->save();

        return redirect('/secrets');
    }
}
encryptString은 시리얼라이즈 없이 문자열을 암호화합니다. 객체나 배열을 암호화하는 경우에는 encrypt를 사용해 주세요.
메서드용도
Crypt::encryptString($value)문자열을 그대로 암호화
Crypt::encrypt($value)값을 시리얼라이즈한 후 암호화(배열·객체 대응)

복호화

Crypt 파사드의 decryptString 메서드로 암호화된 값을 복호화합니다. MAC이 무효인 경우 등 정상적으로 복호화할 수 없을 때는 DecryptException이 던져집니다.
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;

try {
    $decrypted = Crypt::decryptString($encryptedValue);
} catch (DecryptException $e) {
    // 복호화 실패 시의 처리
    abort(400, '유효하지 않은 데이터입니다.');
}
메서드용도
Crypt::decryptString($value)문자열로 복호화
Crypt::decrypt($value)복호화하여 언시리얼라이즈(배열·객체 대응)

모델 캐스트

Eloquent 모델에서 encrypted 캐스트를 사용하면 속성의 암호화·복호화를 자동으로 수행할 수 있습니다.
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected function casts(): array
    {
        return [
            'secret_note'    => 'encrypted',           // 문자열 암호화
            'profile_data'   => 'encrypted:array',     // 배열을 암호화해서 저장
            'preferences'    => 'encrypted:collection',// 컬렉션을 암호화해서 저장
            'metadata'       => 'encrypted:object',    // 객체를 암호화해서 저장
            'settings'       => 'encrypted:json',      // JSON으로 암호화해서 저장
        ];
    }
}
캐스트를 설정하면 모델에 값을 대입·가져올 때 자동으로 암호화·복호화됩니다.
// 자동으로 암호화되어 DB에 저장된다
$user->secret_note = '비밀 메모';
$user->save();

// 자동으로 복호화되어 가져와진다
echo $user->secret_note; // '비밀 메모'
encrypted:* 캐스트는 내부적으로 Crypt::encryptCrypt::decrypt를 사용합니다. 데이터베이스 컬럼 타입은 text 또는 longText를 권장합니다.

실용 예시: 개인정보의 암호화 저장

개인정보(주민등록번호, 신용카드 번호 등)를 데이터베이스에 안전하게 저장하는 전형적인 패턴입니다.

마이그레이션

Schema::create('profiles', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->text('my_number')->nullable();     // 암호화된 값은 text로 저장
    $table->text('bank_account')->nullable();
    $table->timestamps();
});

모델

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    protected $fillable = ['user_id', 'my_number', 'bank_account'];

    protected function casts(): array
    {
        return [
            'my_number'    => 'encrypted',
            'bank_account' => 'encrypted',
        ];
    }
}

컨트롤러

use App\Models\Profile;
use Illuminate\Http\Request;

class ProfileController extends Controller
{
    public function store(Request $request)
    {
        $request->validate([
            'my_number'    => ['required', 'string'],
            'bank_account' => ['required', 'string'],
        ]);

        // 모델이 자동으로 암호화해서 저장한다
        Profile::create([
            'user_id'      => $request->user()->id,
            'my_number'    => $request->my_number,
            'bank_account' => $request->bank_account,
        ]);

        return redirect('/profile');
    }

    public function show(Request $request)
    {
        $profile = $request->user()->profile;

        // 모델이 자동으로 복호화해서 반환한다
        return view('profile.show', ['profile' => $profile]);
    }
}

정리

하고 싶은 것방법
APP_KEY 생성php artisan key:generate
문자열 암호화Crypt::encryptString($value)
문자열 복호화Crypt::decryptString($value)
배열·객체 암호화Crypt::encrypt($value)
모델 속성 자동 암호화'column' => 'encrypted' 캐스트
키 로테이션APP_PREVIOUS_KEYS에 이전 키를 나열

다음 단계

해시

비밀번호의 안전한 해시화와 검증 방법을 배웁니다.

인가

폴리시와 게이트를 사용한 접근 제어를 설명합니다.
마지막 수정일 2026년 7월 13일