Java 암호화 방법: GroupDocs와 함께하는 맞춤형 XOR 암호화

소개

특정 워크플로우를 위해 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 (v23.12 이상).
  • 라이선스가 필요한가요? 테스트용으로는 무료 체험판으로 충분하지만, 프로덕션에서는 정식 라이선스가 필요합니다.
  • 나중에 XOR를 AES로 교체할 수 있나요? 예—encrypt/decrypt 로직만 교체하고 동일한 IDataEncryption 인터페이스를 유지하면 됩니다.

Java에서 맞춤형 암호화란?

IDataEncryption은 데이터를 암호화하고 복호화하는 메서드를 정의하는 GroupDocs.Signature 인터페이스입니다. 맞춤형 암호화를 사용하면 데이터가 저장되거나 전송되기 전에 정확히 어떻게 변환되는지 정의할 수 있습니다. GroupDocs.Signature와 함께 IDataEncryption 인터페이스 구현을 제공하면, 라이브러리가 서명 데이터를 보호해야 할 때 자동으로 해당 코드를 호출합니다. 이 플러그인 모델을 통해 개념 증명을 위한 간단한 XOR 루틴으로 시작하고, 이후 서명 워크플로의 다른 부분을 건드리지 않고 AES‑256으로 교체할 수 있습니다.

맞춤형 암호화가 중요한 이유

기존 알고리즘이 레거시 프로토콜 형식, 엄격한 성능 예산, 혹은 독점 계약 요구 사항과 같은 특정 제약을 충족하지 못할 때 맞춤형 암호화가 유용합니다. 자체 루틴을 구현하면 데이터 변환을 완전히 제어하고 오버헤드를 줄이며 외부 시스템을 재작성하지 않고도 호환성을 보장하면서 GroupDocs의 확장성을 활용할 수 있습니다.

레거시 시스템 통합

오래된 시스템은 종종 매우 특정한 바이트 단위 변환을 요구합니다—대개 단일 바이트 키를 사용한 XOR입니다. 이러한 시스템을 재설계하는 비용이 크기 때문에, 맞춤형 암호기로 기대값을 맞추는 것이 실용적인 경로입니다.

성능 최적화

AES‑256과 같은 표준 알고리즘은 암호학적으로 강력하지만, 특히 저전력 디바이스나 수백만 개의 작은 페이로드를 처리할 때 눈에 띄는 CPU 사이클을 소비합니다. XOR은 바이트당 단일 CPU 명령으로 실행되어 민감하지 않은 데이터에 거의 제로에 가까운 오버헤드를 제공합니다.

독점 요구 사항

일부 계약이나 산업 표준은 맞춤형 알고리즘(예: 정부에서 지정한 “XOR‑mask”)을 요구합니다. 필요한 로직을 직접 구현하면 최신 스택을 유지하면서도 규정을 준수할 수 있습니다.

학습 및 유연성

맞춤형 암호기를 구축하면 바이트 수준 연산, 키 관리, IDataEncryption 인터페이스 기반 계약 설계 등을 이해하게 됩니다. 이러한 지식은 이후 더 정교한 암호학을 도입할 때 큰 도움이 됩니다.

Pro tip: 다른 레이어(TLS, VPN, 데이터베이스 암호화)로 이미 보호된 데이터에만 맞춤형 암호화를 사용하세요. 개인 또는 금융 정보를 보호하기 위해 XOR만을 유일한 방어선으로 의존하지 마십시오.

XOR 이해하기: 기본 개념

XOR(배타적 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 확장 기능이 있는 IDE.
  • Maven 또는 Gradle을 사용한 종속성 관리 (두 가지 모두 지원).

지식 사전 요구 사항

  • Java 클래스, 인터페이스 및 바이트 배열 조작에 익숙함.
  • 대칭 암호 개념에 대한 기본 이해 (XOR 섹션에서 다룸).

위 항목을 모두 충족하면 GroupDocs를 프로젝트에 추가할 준비가 된 것입니다.

GroupDocs.Signature for 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'

직접 다운로드

수동 관리가 필요하면 GroupDocs.Signature for Java releases에서 JAR를 받아 클래스패스에 추가하세요.

라이선스 획득 단계

  1. Free Trial – 체험용 JAR를 다운로드합니다; 출력 파일에 눈에 보이는 워터마크가 포함됩니다.
  2. Temporary License – 전체 기능 테스트를 위한 30일 평가 키를 요청합니다.
  3. 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
}

설명:

  • 가드 절은 0 키(작동하지 않음)와 null 입력을 방지합니다.
  • 새 바이트 배열에 변환된 데이터를 저장하여 원본 버퍼를 변경하지 않도록 합니다.
  • 루프에서 각 바이트를 auto_Key와 XOR합니다.
  • 복호화는 단순히 encrypt를 다시 호출합니다. 동일한 XOR을 두 번 적용하면 원본 바이트가 복원되기 때문입니다.

키 구성 옵션

  • auto_Key는 1에서 255 사이의 0이 아닌 값이어야 합니다. 255를 초과하는 값은 하위 8비트로 잘립니다.
  • 키는 환경 변수, 암호화된 설정 파일, 전용 비밀 관리자를 사용해 안전하게 저장하는 것이 권장됩니다.
  • 프로덕션에서는 이 단순 바이트를 다중 바이트 키 또는 전체 AES 암호로 교체할 가능성이 높지만, 인터페이스는 동일하게 유지됩니다.

키 설정 예시

CustomXOREncryption xor = new CustomXOREncryption();
xor.setKey((byte)0x3C); // set a custom key at runtime
signature.setDataEncryption(xor);

일반 구현 실수

실수문제가 되는 이유수정 방법
키 설정을 잊음암호화가 작동하지 않아 데이터가 평문 그대로 남습니다.encryptor 사용 전에 반드시 setKey()를 호출하거나, 생성자에서 기본 0이 아닌 키를 제공하세요.
null 데이터 무시서명 과정에서 NullPointerException이 발생합니다.두 메서드 시작 부분에 if (data == null) return data;를 추가하세요.
XOR가 안전하다고 가정단일 바이트 키는 밀리초 안에 무차별 대입으로 풀 수 있습니다.XOR는 난독화에만 사용하고, 기밀 페이로드에는 AES‑256으로 전환하세요.
복호화 시 키 불일치데이터를 복구할 수 없게 됩니다.암호화된 페이로드와 함께 키를 저장하거나 키 식별자 매핑을 사용하세요.

보안 고려 사항

민감한 데이터에 XOR가 충분하지 않은 이유

단일 바이트 키를 사용한 XOR은 사실상 암호학적 강도가 거의 없습니다. 공격자는 255가지 가능한 키를 즉시 열거할 수 있습니다. 또한 연산은 통계적 패턴을 누출해 빈도 분석 및 알려진 평문 공격을 쉽게 만들므로, 개인, 금융 또는 기타 기밀 정보를 보호하기 위한 유일한 방어 수단으로 절대 사용해서는 안 됩니다.

XOR가 허용되는 경우

데이터가 TLS, VPN, 데이터베이스 암호화 등 더 강력한 레이어로 이미 보호된 경우에만 XOR를 사용해도 됩니다. 이 경우 마스크는 단순히 우발적인 검사를 방지하거나 레거시 형식을 충족하기 위한 목적에만 사용됩니다. 임시 식별자, 캐시 키, 내부 플래그 등 신뢰된 환경을 벗어나지 않는 경우에 적합합니다.

권장 강력 대안

  • AES‑256 – 업계 표준이며 javax.crypto를 통해 기본 지원됩니다.
  • RSA‑2048 – 작은 대칭 키 암호화에 유용합니다.
  • ChaCha20 – 모바일 CPU에서 높은 성능을 제공합니다.

IDataEncryption 계약이 알고리즘에 구애받지 않기 때문에, AES로 교체하려면 encrypt/decrypt 본문을 적절한 암호 호출로 바꾸기만 하면 됩니다.

실용적인 적용 사례

1. 안전한 문서 서명 워크플로

서명자 메타데이터(ID, 타임스탬프, 부서 등)를 일반 검사를 방지하도록 저장해야 할 수 있습니다. 우리의 XOR 암호기를 사용하면 메타데이터가 바이트 배열 형태로 서명 패키지에 저장되고, PDF 본문은 그대로 유지됩니다.

Signature signature = new Signature("contract.pdf");
signature.setDataEncryption(new CustomXOREncryption());
SignatureResult result = signature.sign("output.pdf", options);

2. 경량 무결성 검사

알려진 상수를 암호화해 문서와 함께 저장합니다. 이후 복호화 후 비교하여 전송 중 파일이 손상되지 않았는지 확인합니다.

3. 레거시 시스템 브리지

오래된 메인프레임은 각 바이트가 0x7F와 XOR된 페이로드를 기대합니다. CustomXOREncryption에 동일한 키를 설정하면 별도의 변환 서비스를 작성하지 않고도 데이터를 교환할 수 있습니다.

성능 고려 사항

순수 속도

XOR은 현대 x86 코어에서 바이트당 약 1 ns 정도로 실행되어 10 MB 페이로드를 10 ms 미만에 암호화합니다. 반면 AES‑256 CBC 모드는 동일 크기에 대해 보통 3‑4배 정도 더 오래 걸립니다.

메모리 사용량

우리 구현은 입력 배열을 복사해 두 배의 메모리를 일시적으로 사용합니다. 50 MB 파일을 처리할 경우 암호화 중에 약 100 MB 힙이 필요합니다. 더 큰 파일을 다뤄야 한다면 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 메모리 관리 모범 사례

  1. 사용 후 키를 0으로 초기화: Arrays.fill(keyArray, (byte)0);
  2. try‑with‑resources를 사용해 스트림을 반드시 닫도록 합니다.
  3. 암호화된 바이트를 String으로 변환하지 말고, 원시 byte[] 형태로 유지합니다.
  4. 여러 대형 문서를 동시에 처리할 때는 VisualVM 같은 도구로 힙을 모니터링합니다.

일반 문제 해결

문제 1 – “복호화된 데이터가 깨져 보임”

직접 답변: 암호화와 복호화에 동일한 XOR 키를 사용했는지 확인하고, 파이프라인 전체에서 데이터를 바이트 배열로 유지하며, 바이트를 손상시킬 수 있는 문자 인코딩 변환을 피하십시오.

발생 원인: 키 불일치, 데이터 절단, 혹은 실수로 String 변환이 발생하면 바이트 패턴이 바뀌어 출력이 읽을 수 없게 됩니다.

문제 2 – “암호화 중 NullPointerException 발생”

직접 답변: encrypt 메서드는 null 입력을 검사하지만 여전히 예외가 발생한다면, 암호화기에 전달하기 전에 원본 바이트 배열이 올바르게 초기화되었는지 확인하십시오.

수정: 호출 코드에 방어적 검사를 추가하거나 서명 데이터가 signature.getSignatureData()로 로드된 후에 암호화를 수행하십시오.

문제 3 – “암호화가 작동하지 않음”

직접 답변: 보통 XOR 키가 0으로 설정된 경우입니다. 0과 XOR하면 원본 바이트가 그대로 유지되므로 출력이 입력과 동일합니다.

해결책: setKey()를 통해 0이 아닌 키를 설정하거나, 생성자에서 기본값을 제공하십시오.

문제 4 – “대형 PDF에서 OutOfMemoryError 발생”

직접 답변: 전체 PDF를 메모리에 로드한 뒤 암호화하면 JVM 힙을 초과할 수 있습니다. 섹션에서 설명한 대로 청크 기반 스트리밍 방식으로 전환하십시오.

팁: -Xmx2g와 같이 최대 힙을 일시적으로 늘릴 수 있지만, 확장성을 위해 청크 처리로 리팩터링하는 것이 바람직합니다.

자주 묻는 질문

Q: 적절한 XOR 키를 어떻게 선택하나요?
A: 1에서 255 사이의 0이 아닌 정수이면 충분하지만, 키 자체는 보안을 제공하지 않습니다. 실제 보호가 필요하면 AES‑256으로 교체하고 키를 안전한 금고에 보관하십시오.

Q: XOR 키를 런타임에 변경할 수 있나요?
A: 예—새 값을 setKey()로 호출하면 됩니다. 기존 키로 암호화된 데이터는 교체 전에 반드시 복호화해야 하며, 그렇지 않으면 해당 데이터에 접근할 수 없습니다.

Q: XOR 암호화 외에 어떤 대안이 있나요?
A: 학습용으로는 Caesar cipher나 Base64(단순 인코딩) 등을 시도해 볼 수 있습니다. 프로덕션에서는 javax.crypto 패키지를 이용해 AES‑256, RSA‑2048, ChaCha20 등을 사용하십시오.

Q: GroupDocs.Signature는 대용량 파일을 암호화할 때 어떻게 처리하나요?
A: 라이브러리는 가능한 경우 PDF 내용을 스트리밍하지만, 맞춤형 IDataEncryption 구현이 데이터 처리 방식을 결정합니다. 메모리 사용량을 최소화하려면 청크 기반 암호화를 구현하십시오.

Q: 이 기능을 웹 애플리케이션에 통합할 수 있나요?
A: 물론 가능합니다. 암호기를 Spring Bean으로 등록하고 Signature 서비스를 주입한 뒤, 키를 환경 변수나 비밀 관리자를 통해 제공하십시오. 각 요청은 별도 스레드에서 데이터를 처리하도록 하여 경쟁 상태를 방지하십시오.

Java에서 XOR 암호화는 어떻게 작동하나요?

Java에서는 ^ 연산자를 사용해 바이트 값을 XOR합니다. 평문을 바이트 배열에 로드하고 각 요소를 순회하면서 byte ^ key를 적용합니다. XOR은 자체 역연산이므로 동일한 키로 동일한 루틴을 다시 실행하면 원본 바이트가 복원되어 암호화와 복호화가 대칭적으로 동작합니다.

GroupDocs와 맞춤형 암호화를 구현하는 단계는 무엇인가요?

맞춤형 암호화를 추가하려면 먼저 IDataEncryption 인터페이스를 구현하는 클래스를 만들고, 해당 알고리즘을 사용해 encrypt와 decrypt 메서드를 코딩합니다. 이후 Signature 객체의 setDataEncryption을 통해 인스턴스를 등록하면 GroupDocs가 서명 데이터를 보호해야 할 때 자동으로 해당 로직을 호출합니다.

결론

우리는 how to encrypt java 코드를 맞춤형 XOR 루틴으로 구현하고, 이를 GroupDocs.Signature와 통합했으며, 이 경량 접근 방식이 가치를 제공하는 상황을 강조했습니다. 기억하세요:

  • XOR는 난독화 목적에만 사용하고, 개인이나 금융 데이터를 보호하기 위해서는 사용하지 마십시오.
  • IDataEncryption 인터페이스는 나중에 더 강력한 알고리즘으로 교체할 수 있는 깔끔한 교체 지점을 제공합니다.
  • 키 관리, 메모리 처리 및 스트리밍은 프로덕션 안정성을 위해 필수입니다.

다음 단계:

  1. 실제 보안을 위해 XOR 로직을 AES‑256으로 교체합니다.
  2. 키 회전 및 안전한 저장을 구현합니다.
  3. 다중 서명 워크플로, 검증, 문서 스탬프 등 GroupDocs의 다른 기능을 탐색합니다.

이제 Java 서명 솔루션에서 암호화를 자유롭게 맞춤화할 수 있는 탄탄한 기반을 갖추었습니다—비즈니스 요구에 정확히 맞게 조정해 보세요!


Last Updated: 2026-06-26
Tested With: GroupDocs.Signature 23.12 for Java
Author: GroupDocs

Related Resources:

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...
}

관련 튜토리얼